in kmsp11/util/crypto_utils.cc [560:606]
absl::Status RsaVerifyRawPkcs1(RSA* public_key, absl::Span<const uint8_t> data,
absl::Span<const uint8_t> signature) {
constexpr size_t kMinRsaKeyBitLength = 2048;
if (RSA_bits(public_key) < kMinRsaKeyBitLength) {
return NewInternalError(
absl::StrFormat("minimum RSA key size is %d bits (got %d)",
kMinRsaKeyBitLength, RSA_bits(public_key)),
SOURCE_LOCATION);
}
constexpr size_t kPkcs1OverheadBytes = 11; // per RFC 3447 section 9.2
size_t max_data_bytes = RSA_size(public_key) - kPkcs1OverheadBytes;
if (data.length() > max_data_bytes) {
return NewInvalidArgumentError(
absl::StrFormat("data is too large (got %d bytes, want <= %d bytes)",
data.length(), max_data_bytes),
CKR_DATA_LEN_RANGE, SOURCE_LOCATION);
}
if (signature.length() != RSA_size(public_key)) {
return NewInvalidArgumentError(
absl::StrFormat(
"signature length mismatches expected (got %d, want %d)",
signature.length(), RSA_size(public_key)),
CKR_SIGNATURE_LEN_RANGE, SOURCE_LOCATION);
}
std::vector<uint8_t> recovered(RSA_size(public_key));
int decrypt_result =
RSA_public_decrypt(signature.size(), signature.data(), recovered.data(),
public_key, RSA_PKCS1_PADDING);
if (decrypt_result == -1) {
return NewInvalidArgumentError(
absl::StrCat("verification failed: ", SslErrorToString()),
CKR_SIGNATURE_INVALID, SOURCE_LOCATION);
}
size_t out_length = decrypt_result;
if (!std::equal(data.begin(), data.end(), recovered.begin(),
recovered.begin() + out_length)) {
return NewInvalidArgumentError(
"verification failed: recovered data mismatches expected",
CKR_SIGNATURE_INVALID, SOURCE_LOCATION);
}
return absl::OkStatus();
}