in kmsp11/util/crypto_utils.cc [238:286]
absl::Status EcdsaVerifyP1363(EC_KEY* public_key, const EVP_MD* hash,
absl::Span<const uint8_t> digest,
absl::Span<const uint8_t> signature) {
if (digest.length() != EVP_MD_size(hash)) {
return NewInvalidArgumentError(
absl::StrFormat("digest length mismatches expected (got %d, want %d)",
digest.length(), EVP_MD_size(hash)),
CKR_DATA_LEN_RANGE, SOURCE_LOCATION);
}
if (signature.length() % 2 == 1) {
return NewInvalidArgumentError(
absl::StrFormat(
"signature of length %d contains an uneven number of bytes",
signature.length()),
CKR_SIGNATURE_LEN_RANGE, SOURCE_LOCATION);
}
size_t max_len = EcdsaSigLengthP1363(EC_KEY_get0_group(public_key));
if (signature.length() > max_len) {
return NewInvalidArgumentError(
absl::StrFormat(
"provided signature length exceeds maximum (got %d, want <= %d)",
signature.length(), max_len),
CKR_SIGNATURE_LEN_RANGE, SOURCE_LOCATION);
}
bssl::UniquePtr<ECDSA_SIG> sig(ECDSA_SIG_new());
int n_len = signature.length() / 2;
bssl::UniquePtr<BIGNUM> r(BN_new());
bssl::UniquePtr<BIGNUM> s(BN_new());
if (!BN_bin2bn(&signature[0], n_len, r.get()) ||
!BN_bin2bn(&signature[n_len], n_len, s.get()) ||
!ECDSA_SIG_set0(sig.get(), r.release(), s.release())) {
return NewInternalError(
absl::StrCat("error parsing signature component: ", SslErrorToString()),
SOURCE_LOCATION);
}
if (ECDSA_do_verify(digest.data(), digest.size(), sig.get(), public_key) !=
1) {
return NewInvalidArgumentError(
absl::StrCat("verification failed: ", SslErrorToString()),
CKR_SIGNATURE_INVALID, SOURCE_LOCATION);
}
return absl::OkStatus();
}