// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/rsa.h>

#include <assert.h>
#include <limits.h>
#include <string.h>

#include <iterator>

#include <openssl/bn.h>
#include <openssl/digest.h>
#include <openssl/engine.h>
#include <openssl/err.h>
#include <openssl/ex_data.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
#include <openssl/nid.h>

#include "../../internal.h"
#include "../../mem_internal.h"
#include "../bcm_interface.h"
#include "../bn/internal.h"
#include "../delocate.h"
#include "internal.h"


using namespace bssl;

// RSA_R_BLOCK_TYPE_IS_NOT_02 is part of the legacy SSLv23 padding scheme.
// Cryptography.io depends on this error code.
OPENSSL_DECLARE_ERROR_REASON(RSA, BLOCK_TYPE_IS_NOT_02)

DEFINE_STATIC_EX_DATA_CLASS(g_rsa_ex_data_class)

static int bn_dup_into(UniquePtr<BIGNUM> *dst, const BIGNUM *src) {
  if (src == nullptr) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  dst->reset(BN_dup(src));
  return *dst != nullptr;
}

RSA *RSA_new_public_key(const BIGNUM *n, const BIGNUM *e) {
  RSAImpl *rsa = FromOpaque(RSA_new());
  if (rsa == nullptr ||            //
      !bn_dup_into(&rsa->n, n) ||  //
      !bn_dup_into(&rsa->e, e) ||  //
      !RSA_check_key(rsa)) {
    RSA_free(rsa);
    return nullptr;
  }

  return rsa;
}

RSA *RSA_new_private_key(const BIGNUM *n, const BIGNUM *e, const BIGNUM *d,
                         const BIGNUM *p, const BIGNUM *q, const BIGNUM *dmp1,
                         const BIGNUM *dmq1, const BIGNUM *iqmp) {
  RSAImpl *rsa = FromOpaque(RSA_new());
  if (rsa == nullptr ||                  //
      !bn_dup_into(&rsa->n, n) ||        //
      !bn_dup_into(&rsa->e, e) ||        //
      !bn_dup_into(&rsa->d, d) ||        //
      !bn_dup_into(&rsa->p, p) ||        //
      !bn_dup_into(&rsa->q, q) ||        //
      !bn_dup_into(&rsa->dmp1, dmp1) ||  //
      !bn_dup_into(&rsa->dmq1, dmq1) ||  //
      !bn_dup_into(&rsa->iqmp, iqmp) ||  //
      !RSA_check_key(rsa)) {
    RSA_free(rsa);
    return nullptr;
  }

  return rsa;
}

RSA *RSA_new_private_key_no_crt(const BIGNUM *n, const BIGNUM *e,
                                const BIGNUM *d) {
  RSAImpl *rsa = FromOpaque(RSA_new());
  if (rsa == nullptr ||            //
      !bn_dup_into(&rsa->n, n) ||  //
      !bn_dup_into(&rsa->e, e) ||  //
      !bn_dup_into(&rsa->d, d) ||  //
      !RSA_check_key(rsa)) {
    RSA_free(rsa);
    return nullptr;
  }

  return rsa;
}

RSA *RSA_new_private_key_no_e(const BIGNUM *n, const BIGNUM *d) {
  RSAImpl *rsa = FromOpaque(RSA_new());
  if (rsa == nullptr) {
    return nullptr;
  }

  rsa->flags |= RSA_FLAG_NO_PUBLIC_EXPONENT;
  if (!bn_dup_into(&rsa->n, n) ||  //
      !bn_dup_into(&rsa->d, d) ||  //
      !RSA_check_key(rsa)) {
    RSA_free(rsa);
    return nullptr;
  }

  return rsa;
}

RSA *RSA_new_public_key_large_e(const BIGNUM *n, const BIGNUM *e) {
  RSAImpl *rsa = FromOpaque(RSA_new());
  if (rsa == nullptr) {
    return nullptr;
  }

  rsa->flags |= RSA_FLAG_LARGE_PUBLIC_EXPONENT;
  if (!bn_dup_into(&rsa->n, n) ||  //
      !bn_dup_into(&rsa->e, e) ||  //
      !RSA_check_key(rsa)) {
    RSA_free(rsa);
    return nullptr;
  }

  return rsa;
}

RSA *RSA_new_private_key_large_e(const BIGNUM *n, const BIGNUM *e,
                                 const BIGNUM *d, const BIGNUM *p,
                                 const BIGNUM *q, const BIGNUM *dmp1,
                                 const BIGNUM *dmq1, const BIGNUM *iqmp) {
  RSAImpl *rsa = FromOpaque(RSA_new());
  if (rsa == nullptr) {
    return nullptr;
  }

  rsa->flags |= RSA_FLAG_LARGE_PUBLIC_EXPONENT;
  if (!bn_dup_into(&rsa->n, n) ||        //
      !bn_dup_into(&rsa->e, e) ||        //
      !bn_dup_into(&rsa->d, d) ||        //
      !bn_dup_into(&rsa->p, p) ||        //
      !bn_dup_into(&rsa->q, q) ||        //
      !bn_dup_into(&rsa->dmp1, dmp1) ||  //
      !bn_dup_into(&rsa->dmq1, dmq1) ||  //
      !bn_dup_into(&rsa->iqmp, iqmp) ||  //
      !RSA_check_key(rsa)) {
    RSA_free(rsa);
    return nullptr;
  }

  return rsa;
}

RSAImpl::RSAImpl(const ENGINE *engine)
    : RefCounted(CheckSubClass()),
      meth(engine ? ENGINE_get_RSA_method(engine) : nullptr) {
  if (meth == nullptr) {
    meth = const_cast<RSA_METHOD *>(RSA_default_method());
  }
  METHOD_ref(meth);
  flags = meth->flags;
  CRYPTO_new_ex_data(&ex_data);
}

RSA *RSA_new() { return RSA_new_method(nullptr); }

RSA *RSA_new_method(const ENGINE *engine) {
  UniquePtr<RSAImpl> rsa(New<RSAImpl>(engine));
  if (rsa == nullptr) {
    return nullptr;
  }

  if (rsa->meth->init && !rsa->meth->init(rsa.get())) {
    METHOD_unref(rsa->meth);
    rsa->meth = nullptr;
    return nullptr;
  }

  return rsa.release();
}

RSA *RSA_new_method_no_e(const ENGINE *engine, const BIGNUM *n) {
  RSAImpl *rsa = FromOpaque(RSA_new_method(engine));
  if (rsa == nullptr || !bn_dup_into(&rsa->n, n)) {
    RSA_free(rsa);
    return nullptr;
  }
  rsa->flags |= RSA_FLAG_NO_PUBLIC_EXPONENT;
  return rsa;
}

RSAImpl::~RSAImpl() {
  if (meth != nullptr && meth->finish != nullptr) {
    meth->finish(this);
  }
  METHOD_unref(meth);

  CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), &ex_data);
}

void RSA_free(RSA *rsa) {
  if (rsa != nullptr) {
    FromOpaque(rsa)->DecRefInternal();
  }
}

int RSA_up_ref(RSA *rsa) {
  FromOpaque(rsa)->UpRefInternal();
  return 1;
}

unsigned RSA_bits(const RSA *rsa) {
  return BN_num_bits(FromOpaque(rsa)->n.get());
}

const BIGNUM *RSA_get0_n(const RSA *rsa) { return FromOpaque(rsa)->n.get(); }

const BIGNUM *RSA_get0_e(const RSA *rsa) { return FromOpaque(rsa)->e.get(); }

const BIGNUM *RSA_get0_d(const RSA *rsa) { return FromOpaque(rsa)->d.get(); }

const BIGNUM *RSA_get0_p(const RSA *rsa) { return FromOpaque(rsa)->p.get(); }

const BIGNUM *RSA_get0_q(const RSA *rsa) { return FromOpaque(rsa)->q.get(); }

const BIGNUM *RSA_get0_dmp1(const RSA *rsa) {
  return FromOpaque(rsa)->dmp1.get();
}

const BIGNUM *RSA_get0_dmq1(const RSA *rsa) {
  return FromOpaque(rsa)->dmq1.get();
}

const BIGNUM *RSA_get0_iqmp(const RSA *rsa) {
  return FromOpaque(rsa)->iqmp.get();
}

void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e,
                  const BIGNUM **out_d) {
  auto *impl = FromOpaque(rsa);
  if (out_n != nullptr) {
    *out_n = impl->n.get();
  }
  if (out_e != nullptr) {
    *out_e = impl->e.get();
  }
  if (out_d != nullptr) {
    *out_d = impl->d.get();
  }
}

void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p,
                      const BIGNUM **out_q) {
  auto *impl = FromOpaque(rsa);
  if (out_p != nullptr) {
    *out_p = impl->p.get();
  }
  if (out_q != nullptr) {
    *out_q = impl->q.get();
  }
}

void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1,
                         const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) {
  auto *impl = FromOpaque(rsa);
  if (out_dmp1 != nullptr) {
    *out_dmp1 = impl->dmp1.get();
  }
  if (out_dmq1 != nullptr) {
    *out_dmq1 = impl->dmq1.get();
  }
  if (out_iqmp != nullptr) {
    *out_iqmp = impl->iqmp.get();
  }
}

int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) {
  auto *impl = FromOpaque(rsa);

  if ((impl->n == nullptr && n == nullptr) ||
      (impl->e == nullptr && e == nullptr)) {
    return 0;
  }

  if (n != nullptr) {
    impl->n.reset(n);
  }
  if (e != nullptr) {
    impl->e.reset(e);
  }
  if (d != nullptr) {
    impl->d.reset(d);
  }

  rsa_invalidate_key(rsa);
  return 1;
}

int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) {
  auto *impl = FromOpaque(rsa);

  if ((impl->p == nullptr && p == nullptr) ||
      (impl->q == nullptr && q == nullptr)) {
    return 0;
  }

  if (p != nullptr) {
    impl->p.reset(p);
  }
  if (q != nullptr) {
    impl->q.reset(q);
  }

  rsa_invalidate_key(rsa);
  return 1;
}

int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) {
  auto *impl = FromOpaque(rsa);

  if ((impl->dmp1 == nullptr && dmp1 == nullptr) ||
      (impl->dmq1 == nullptr && dmq1 == nullptr) ||
      (impl->iqmp == nullptr && iqmp == nullptr)) {
    return 0;
  }

  if (dmp1 != nullptr) {
    impl->dmp1.reset(dmp1);
  }
  if (dmq1 != nullptr) {
    impl->dmq1.reset(dmq1);
  }
  if (iqmp != nullptr) {
    impl->iqmp.reset(iqmp);
  }

  rsa_invalidate_key(rsa);
  return 1;
}

static int rsa_sign_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out,
                                     size_t max_out, const uint8_t *in,
                                     size_t in_len, int padding) {
  auto *impl = FromOpaque(rsa);

  if (impl->meth->sign_raw) {
    return impl->meth->sign_raw(rsa, out_len, out, max_out, in, in_len,
                                padding);
  }

  return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding);
}

int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                 const uint8_t *in, size_t in_len, int padding) {
  boringssl_ensure_rsa_sign_self_test();
  return rsa_sign_raw_no_self_test(rsa, out_len, out, max_out, in, in_len,
                                   padding);
}

unsigned RSA_size(const RSA *rsa) {
  return BN_num_bytes(FromOpaque(rsa)->n.get());
}

int RSA_is_opaque(const RSA *rsa) {
  auto *impl = FromOpaque(rsa);
  return impl->meth && (impl->meth->flags & RSA_FLAG_OPAQUE);
}

int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused,
                         CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) {
  return CRYPTO_get_ex_new_index_ex(g_rsa_ex_data_class_bss_get(), argl, argp,
                                    free_func);
}

int RSA_set_ex_data(RSA *rsa, int idx, void *arg) {
  auto *impl = FromOpaque(rsa);
  return CRYPTO_set_ex_data(&impl->ex_data, idx, arg);
}

void *RSA_get_ex_data(const RSA *rsa, int idx) {
  auto *impl = FromOpaque(rsa);
  return CRYPTO_get_ex_data(&impl->ex_data, idx);
}

// SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's
// the length of an MD5 and SHA1 hash.
static const unsigned SSL_SIG_LENGTH = 36;

// pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is
// to be signed with PKCS#1.
struct pkcs1_sig_prefix {
  // nid identifies the hash function.
  int nid;
  // hash_len is the expected length of the hash function.
  uint8_t hash_len;
  // len is the number of bytes of |bytes| which are valid.
  uint8_t len;
  // bytes contains the DER bytes.
  uint8_t bytes[19];
};

// kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with
// different hash functions.
static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
    {
        NID_md5,
        MD5_DIGEST_LENGTH,
        18,
        {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
         0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
    },
    {
        NID_sha1,
        SHA_DIGEST_LENGTH,
        15,
        {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
         0x00, 0x04, 0x14},
    },
    {
        NID_sha224,
        SHA224_DIGEST_LENGTH,
        19,
        {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
         0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
    },
    {
        NID_sha256,
        SHA256_DIGEST_LENGTH,
        19,
        {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
         0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
    },
    {
        NID_sha384,
        SHA384_DIGEST_LENGTH,
        19,
        {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
         0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
    },
    {
        NID_sha512,
        SHA512_DIGEST_LENGTH,
        19,
        {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
         0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
    },
    {
        NID_undef,
        0,
        0,
        {0},
    },
};

static int rsa_check_digest_size(int hash_nid, size_t digest_len) {
  if (hash_nid == NID_md5_sha1) {
    if (digest_len != SSL_SIG_LENGTH) {
      OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
      return 0;
    }
    return 1;
  }

  for (size_t i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
    const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
    if (sig_prefix->nid == hash_nid) {
      if (digest_len != sig_prefix->hash_len) {
        OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
        return 0;
      }
      return 1;
    }
  }

  OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
  return 0;
}

int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
                         int *is_alloced, int hash_nid, const uint8_t *digest,
                         size_t digest_len) {
  if (!rsa_check_digest_size(hash_nid, digest_len)) {
    return 0;
  }

  if (hash_nid == NID_md5_sha1) {
    // The length should already have been checked.
    assert(digest_len == SSL_SIG_LENGTH);
    *out_msg = (uint8_t *)digest;
    *out_msg_len = digest_len;
    *is_alloced = 0;
    return 1;
  }

  for (size_t i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) {
    const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i];
    if (sig_prefix->nid != hash_nid) {
      continue;
    }

    // The length should already have been checked.
    assert(digest_len == sig_prefix->hash_len);
    const uint8_t *prefix = sig_prefix->bytes;
    size_t prefix_len = sig_prefix->len;
    size_t signed_msg_len = prefix_len + digest_len;
    if (signed_msg_len < prefix_len) {
      OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
      return 0;
    }

    uint8_t *signed_msg =
        reinterpret_cast<uint8_t *>(OPENSSL_malloc(signed_msg_len));
    if (!signed_msg) {
      return 0;
    }

    OPENSSL_memcpy(signed_msg, prefix, prefix_len);
    OPENSSL_memcpy(signed_msg + prefix_len, digest, digest_len);

    *out_msg = signed_msg;
    *out_msg_len = signed_msg_len;
    *is_alloced = 1;

    return 1;
  }

  OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
  return 0;
}

int bssl::rsa_sign_no_self_test(int hash_nid, const uint8_t *digest,
                                size_t digest_len, uint8_t *out,
                                unsigned *out_len, RSA *rsa) {
  auto *impl = FromOpaque(rsa);

  if (impl->meth->sign) {
    if (!rsa_check_digest_size(hash_nid, digest_len)) {
      return 0;
    }
    // All supported digest lengths fit in |unsigned|.
    assert(digest_len <= EVP_MAX_MD_SIZE);
    static_assert(EVP_MAX_MD_SIZE <= UINT_MAX, "digest too long");
    return impl->meth->sign(hash_nid, digest, (unsigned)digest_len, out,
                            out_len, rsa);
  }

  const unsigned rsa_size = RSA_size(rsa);
  int ret = 0;
  uint8_t *signed_msg = nullptr;
  size_t signed_msg_len = 0;
  int signed_msg_is_alloced = 0;
  size_t size_t_out_len;
  if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
                            &signed_msg_is_alloced, hash_nid, digest,
                            digest_len) ||
      !rsa_sign_raw_no_self_test(rsa, &size_t_out_len, out, rsa_size,
                                 signed_msg, signed_msg_len,
                                 RSA_PKCS1_PADDING)) {
    goto err;
  }

  if (size_t_out_len > UINT_MAX) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
    goto err;
  }

  *out_len = (unsigned)size_t_out_len;
  ret = 1;

err:
  if (signed_msg_is_alloced) {
    OPENSSL_free(signed_msg);
  }
  return ret;
}

int RSA_sign(int hash_nid, const uint8_t *digest, size_t digest_len,
             uint8_t *out, unsigned *out_len, RSA *rsa) {
  boringssl_ensure_rsa_sign_self_test();

  return rsa_sign_no_self_test(hash_nid, digest, digest_len, out, out_len, rsa);
}

int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
                      const uint8_t *digest, size_t digest_len,
                      const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len) {
  if (digest_len != EVP_MD_size(md)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
    return 0;
  }

  size_t padded_len = RSA_size(rsa);
  uint8_t *padded = reinterpret_cast<uint8_t *>(OPENSSL_malloc(padded_len));
  if (padded == nullptr) {
    return 0;
  }

  int ret = RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, digest, md, mgf1_md,
                                           salt_len) &&
            RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len,
                         RSA_NO_PADDING);
  OPENSSL_free(padded);
  return ret;
}

int bssl::rsa_verify_no_self_test(int hash_nid, const uint8_t *digest,
                                  size_t digest_len, const uint8_t *sig,
                                  size_t sig_len, RSA *rsa) {
  auto *impl = FromOpaque(rsa);
  if (impl->n == nullptr || impl->e == nullptr) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
    return 0;
  }

  const size_t rsa_size = RSA_size(rsa);
  uint8_t *buf = nullptr;
  int ret = 0;
  uint8_t *signed_msg = nullptr;
  size_t signed_msg_len = 0, len;
  int signed_msg_is_alloced = 0;

  if (hash_nid == NID_md5_sha1 && digest_len != SSL_SIG_LENGTH) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
    return 0;
  }

  buf = reinterpret_cast<uint8_t *>(OPENSSL_malloc(rsa_size));
  if (!buf) {
    return 0;
  }

  if (!rsa_verify_raw_no_self_test(rsa, &len, buf, rsa_size, sig, sig_len,
                                   RSA_PKCS1_PADDING) ||
      !RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
                            &signed_msg_is_alloced, hash_nid, digest,
                            digest_len)) {
    goto out;
  }

  // Check that no other information follows the hash value (FIPS 186-5 Section
  // 5.4) and it matches the expected hash.
  if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
    goto out;
  }

  ret = 1;

out:
  OPENSSL_free(buf);
  if (signed_msg_is_alloced) {
    OPENSSL_free(signed_msg);
  }
  return ret;
}

int RSA_verify(int hash_nid, const uint8_t *digest, size_t digest_len,
               const uint8_t *sig, size_t sig_len, RSA *rsa) {
  boringssl_ensure_rsa_verify_self_test();
  return rsa_verify_no_self_test(hash_nid, digest, digest_len, sig, sig_len,
                                 rsa);
}

int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len,
                        const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len,
                        const uint8_t *sig, size_t sig_len) {
  if (digest_len != EVP_MD_size(md)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
    return 0;
  }

  size_t em_len = RSA_size(rsa);
  uint8_t *em = reinterpret_cast<uint8_t *>(OPENSSL_malloc(em_len));
  if (em == nullptr) {
    return 0;
  }

  int ret = 0;
  if (!RSA_verify_raw(rsa, &em_len, em, em_len, sig, sig_len, RSA_NO_PADDING)) {
    goto err;
  }

  if (em_len != RSA_size(rsa)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  ret = RSA_verify_PKCS1_PSS_mgf1(rsa, digest, md, mgf1_md, em, salt_len);

err:
  OPENSSL_free(em);
  return ret;
}

static int check_mod_inverse(int *out_ok, const BIGNUM *a, const BIGNUM *ainv,
                             const BIGNUM *m, unsigned m_min_bits,
                             BN_CTX *ctx) {
  if (BN_is_negative(ainv) ||
      constant_time_declassify_int(BN_cmp(ainv, m) >= 0)) {
    *out_ok = 0;
    return 1;
  }

  // Note |bn_mul_consttime| and |bn_div_consttime| do not scale linearly, but
  // checking |ainv| is in range bounds the running time, assuming |m|'s bounds
  // were checked by the caller.
  BN_CTXScope scope(ctx);
  BIGNUM *tmp = BN_CTX_get(ctx);
  if (tmp == nullptr ||  //
      !bn_mul_consttime(tmp, a, ainv, ctx) ||
      !bn_div_consttime(nullptr, tmp, tmp, m, m_min_bits, ctx)) {
    return 0;
  }
  *out_ok = constant_time_declassify_int(BN_is_one(tmp));
  return 1;
}

int RSA_check_key(const RSA *key) {
  // TODO(davidben): RSA key initialization is spread across
  // |rsa_check_public_key|, |RSA_check_key|, |freeze_private_key|, and
  // |BN_MONT_CTX_set_locked| as a result of API issues. See
  // https://crbug.com/boringssl/316. As a result, we inconsistently check RSA
  // invariants. We should fix this and integrate that logic.

  if (!rsa_check_public_key(key)) {
    return 0;
  }

  auto *impl = FromOpaque(key);
  if ((impl->p != nullptr) != (impl->q != nullptr)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
    return 0;
  }

  // |impl->d| must be bounded by |impl->n|. This ensures bounds on |RSA_bits|
  // translate to bounds on the running time of private key operations.
  if (impl->d != nullptr && (BN_is_negative(impl->d.get()) ||
                             BN_cmp(impl->d.get(), impl->n.get()) >= 0)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_D_OUT_OF_RANGE);
    return 0;
  }

  if (impl->d == nullptr || impl->p == nullptr) {
    // For a public key, or without p and q, there's nothing that can be
    // checked.
    return 1;
  }

  BN_CTX *ctx = BN_CTX_new();
  if (ctx == nullptr) {
    return 0;
  }

  BIGNUM tmp, de, pm1, qm1, dmp1, dmq1;
  int ok = 0;
  bool has_crt_values;
  unsigned pm1_bits, qm1_bits;
  BN_init(&tmp);
  BN_init(&de);
  BN_init(&pm1);
  BN_init(&qm1);
  BN_init(&dmp1);
  BN_init(&dmq1);

  // Check that p * q == n. Before we multiply, we check that p and q are in
  // bounds, to avoid a DoS vector in |bn_mul_consttime| below. Note that
  // n was bound by |rsa_check_public_key|. This also implicitly checks p and q
  // are odd, which is a necessary condition for Montgomery reduction.
  if (BN_is_negative(impl->p.get()) ||
      constant_time_declassify_int(BN_cmp(impl->p.get(), impl->n.get()) >= 0) ||
      BN_is_negative(impl->q.get()) ||
      constant_time_declassify_int(BN_cmp(impl->q.get(), impl->n.get()) >= 0)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
    goto out;
  }
  if (!bn_mul_consttime(&tmp, impl->p.get(), impl->q.get(), ctx)) {
    OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
    goto out;
  }
  if (BN_cmp(&tmp, impl->n.get()) != 0) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
    goto out;
  }

  // d must be an inverse of e mod the Carmichael totient, lcm(p-1, q-1), but it
  // may be unreduced because other implementations use the Euler totient. We
  // simply check that d * e is one mod p-1 and mod q-1. Note d and e were bound
  // by earlier checks in this function.
  if (!bn_usub_consttime(&pm1, impl->p.get(), BN_value_one()) ||
      !bn_usub_consttime(&qm1, impl->q.get(), BN_value_one())) {
    OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
    goto out;
  }
  pm1_bits = BN_num_bits(&pm1);
  qm1_bits = BN_num_bits(&qm1);
  if (!bn_mul_consttime(&de, impl->d.get(), impl->e.get(), ctx) ||
      !bn_div_consttime(nullptr, &tmp, &de, &pm1, pm1_bits, ctx) ||
      !bn_div_consttime(nullptr, &de, &de, &qm1, qm1_bits, ctx)) {
    OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
    goto out;
  }

  if (constant_time_declassify_int(!BN_is_one(&tmp)) ||
      constant_time_declassify_int(!BN_is_one(&de))) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
    goto out;
  }

  has_crt_values = impl->dmp1 != nullptr;
  if (has_crt_values != (impl->dmq1 != nullptr) ||
      has_crt_values != (impl->iqmp != nullptr)) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
    goto out;
  }

  if (has_crt_values) {
    int dmp1_ok, dmq1_ok, iqmp_ok;
    if (!check_mod_inverse(&dmp1_ok, impl->e.get(), impl->dmp1.get(), &pm1,
                           pm1_bits, ctx) ||
        !check_mod_inverse(&dmq1_ok, impl->e.get(), impl->dmq1.get(), &qm1,
                           qm1_bits, ctx) ||
        // |p| is odd, so |pm1| and |p| have the same bit width. If they didn't,
        // we only need a lower bound anyway.
        !check_mod_inverse(&iqmp_ok, impl->q.get(), impl->iqmp.get(),
                           impl->p.get(), pm1_bits, ctx)) {
      OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
      goto out;
    }

    if (!dmp1_ok || !dmq1_ok || !iqmp_ok) {
      OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
      goto out;
    }
  }

  ok = 1;

out:
  BN_free(&tmp);
  BN_free(&de);
  BN_free(&pm1);
  BN_free(&qm1);
  BN_free(&dmp1);
  BN_free(&dmq1);
  BN_CTX_free(ctx);

  return ok;
}


// This is the product of the 132 smallest odd primes, from 3 to 751.
static const BN_ULONG kSmallFactorsLimbs[] = {TOBN(0xc4309333, 0x3ef4e3e1),
                                              TOBN(0x71161eb6, 0xcd2d655f),
                                              TOBN(0x95e2238c, 0x0bf94862),
                                              TOBN(0x3eb233d3, 0x24f7912b),
                                              TOBN(0x6b55514b, 0xbf26c483),
                                              TOBN(0x0a84d817, 0x5a144871),
                                              TOBN(0x77d12fee, 0x9b82210a),
                                              TOBN(0xdb5b93c2, 0x97f050b3),
                                              TOBN(0x4acad6b9, 0x4d6c026b),
                                              TOBN(0xeb7751f3, 0x54aec893),
                                              TOBN(0xdba53368, 0x36bc85c4),
                                              TOBN(0xd85a1b28, 0x7f5ec78e),
                                              TOBN(0x2eb072d8, 0x6b322244),
                                              TOBN(0xbba51112, 0x5e2b3aea),
                                              TOBN(0x36ed1a6c, 0x0e2486bf),
                                              TOBN(0x5f270460, 0xec0c5727),
                                              0x000017b1};

DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) {
  out->d = const_cast<BN_ULONG *>(kSmallFactorsLimbs);
  out->width = std::size(kSmallFactorsLimbs);
  out->dmax = out->width;
  out->neg = 0;
  out->flags = BN_FLG_STATIC_DATA;
}

int RSA_check_fips(RSA *key) {
  if (!RSA_check_key(key)) {
    return 0;
  }

  BN_CTX *ctx = BN_CTX_new();
  if (ctx == nullptr) {
    return 0;
  }

  BIGNUM small_gcd;
  BN_init(&small_gcd);

  int ret = 1;

  // Perform partial public key validation of RSA keys (SP 800-89 5.3.3).
  // Although this is not for primality testing, SP 800-89 cites an RSA
  // primality testing algorithm, so we use |BN_prime_checks_for_generation| to
  // match. This is only a plausibility test and we expect the value to be
  // composite, so too few iterations will cause us to reject the key, not use
  // an implausible one.
  //
  // |key->e| may be nullptr if created with |RSA_new_private_key_no_e|.
  enum bn_primality_result_t primality_result;
  auto *impl = FromOpaque(key);
  if (impl->e.get() == nullptr ||          //
      BN_num_bits(impl->e.get()) <= 16 ||  //
      BN_num_bits(impl->e.get()) > 256 ||  //
      !BN_is_odd(impl->n.get()) ||         //
      !BN_is_odd(impl->e.get()) ||
      !BN_gcd(&small_gcd, impl->n.get(), g_small_factors(), ctx) ||
      !BN_is_one(&small_gcd) ||
      !BN_enhanced_miller_rabin_primality_test(&primality_result, impl->n.get(),
                                               BN_prime_checks_for_generation,
                                               ctx, nullptr) ||
      primality_result != bn_non_prime_power_composite) {
    OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED);
    ret = 0;
  }

  BN_free(&small_gcd);
  BN_CTX_free(ctx);

  if (!ret || impl->d == nullptr || impl->p == nullptr) {
    // On a failure or on only a public key, there's nothing else can be
    // checked.
    return ret;
  }

  // FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG,
  // section 9.9, it is not known whether |rsa| will be used for signing or
  // encryption, so either pair-wise consistency self-test is acceptable. We
  // perform a signing test.
  uint8_t data[32] = {0};
  unsigned sig_len = RSA_size(key);
  uint8_t *sig = reinterpret_cast<uint8_t *>(OPENSSL_malloc(sig_len));
  if (sig == nullptr) {
    return 0;
  }

  if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    ret = 0;
    goto cleanup;
  }
  if (boringssl_fips_break_test("RSA_PWCT")) {
    data[0] = ~data[0];
  }
  if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) {
    OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
    ret = 0;
  }

cleanup:
  OPENSSL_free(sig);

  return ret;
}

int bssl::rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out,
                                             const uint8_t *in, size_t len) {
  auto *impl = FromOpaque(rsa);

  if (impl->meth->private_transform) {
    return impl->meth->private_transform(rsa, out, in, len);
  }

  return rsa_default_private_transform(rsa, out, in, len);
}

int bssl::rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
                                size_t len) {
  boringssl_ensure_rsa_sign_self_test();
  return rsa_private_transform_no_self_test(rsa, out, in, len);
}

int RSA_flags(const RSA *rsa) {
  auto *impl = FromOpaque(rsa);
  return impl->flags;
}

int RSA_test_flags(const RSA *rsa, int flags) {
  auto *impl = FromOpaque(rsa);
  return impl->flags & flags;
}
