Fixup some minor issues in HPKE P-256 key derivation

p256_private_key_from_seed should reject the zero scalar. It is
computationally infeasible to find any input that hits this case, so no
unit test or practical consequence, but we should match the spec I
suppose.

See https://www.rfc-editor.org/rfc/rfc9180.html#name-derivekeypair

Also add some missing error checks for p256_public_from_private. Other
than the computationally infeasible zero scalar above, this is
impossible except for ec_point_mul_scalar_base's fault protection logic
(which is impossible unless there's another bug or CPU fault).

Change-Id: I6961601f4036829c8dba990922b4135c0e141df8
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/95188
Auto-Submit: David Benjamin <davidben@google.com>
Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/hpke/hpke.cc b/crypto/hpke/hpke.cc
index 130a9b3..2365a53 100644
--- a/crypto/hpke/hpke.cc
+++ b/crypto/hpke/hpke.cc
@@ -451,9 +451,10 @@
       return 0;
     }
 
-    // This checks that the scalar is less than the order.
+    // |ec_scalar_from_bytes| checks that the scalar is less than the order.
     if (ec_scalar_from_bytes(group, &private_scalar, out_priv,
-                             P256_PRIVATE_KEY_LEN)) {
+                             P256_PRIVATE_KEY_LEN) &&
+        !ec_scalar_is_zero(group, &private_scalar)) {
       return 1;
     }
   }
@@ -526,10 +527,10 @@
     return 0;
   }
   uint8_t private_key[P256_PRIVATE_KEY_LEN];
-  if (!p256_private_key_from_seed(private_key, seed, seed_len)) {
+  if (!p256_private_key_from_seed(private_key, seed, seed_len) ||
+      !p256_public_from_private(out_enc, private_key)) {
     return 0;
   }
-  p256_public_from_private(out_enc, private_key);
 
   uint8_t dh[P256_SHARED_KEY_LEN];
   if (peer_public_key_len != P256_PUBLIC_VALUE_LEN ||
@@ -591,10 +592,10 @@
     return 0;
   }
   uint8_t private_key[P256_PRIVATE_KEY_LEN];
-  if (!p256_private_key_from_seed(private_key, seed, seed_len)) {
+  if (!p256_private_key_from_seed(private_key, seed, seed_len) ||
+      !p256_public_from_private(out_enc, private_key)) {
     return 0;
   }
-  p256_public_from_private(out_enc, private_key);
 
   uint8_t dh[2 * P256_SHARED_KEY_LEN];
   if (peer_public_key_len != P256_PUBLIC_VALUE_LEN ||