absl::Status RsaVerifyPss()

in kmsp11/util/crypto_utils.cc [519:558]


absl::Status RsaVerifyPss(EVP_PKEY* 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);
  }

  int rsa_size = RSA_size(EVP_PKEY_get0_RSA(public_key));
  if (int(signature.length()) != rsa_size) {
    return NewInvalidArgumentError(
        absl::StrFormat(
            "signature length mismatches expected (got %d, want %d)",
            signature.length(), rsa_size),
        CKR_SIGNATURE_LEN_RANGE, SOURCE_LOCATION);
  }

  bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(public_key, nullptr));
  if (!ctx || EVP_PKEY_verify_init(ctx.get()) != 1 ||
      EVP_PKEY_CTX_set_signature_md(ctx.get(), hash) != 1 ||
      EVP_PKEY_CTX_set_rsa_padding(ctx.get(), RSA_PKCS1_PSS_PADDING) != 1 ||
      EVP_PKEY_CTX_set_rsa_mgf1_md(ctx.get(), hash) != 1 ||
      EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), -1) != 1) {
    return NewInternalError(
        absl::StrCat("error building verification context: ",
                     SslErrorToString()),
        SOURCE_LOCATION);
  }

  if (EVP_PKEY_verify(ctx.get(), signature.data(), signature.size(),
                      digest.data(), digest.size()) != 1) {
    return NewInvalidArgumentError(
        absl::StrCat("verification failed: ", SslErrorToString()),
        CKR_SIGNATURE_INVALID, SOURCE_LOCATION);
  }

  return absl::OkStatus();
}