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 ||