absl::Status RsaVerifyRawPkcs1()

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();
}