/*
 * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2018-2019, Oracle and/or its affiliates.  All rights reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/core.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "crypto/bn.h"
#include "crypto/security_bits.h"
#include "rsa_local.h"

#define RSA_FIPS1864_MIN_KEYGEN_KEYSIZE 2048
#define RSA_FIPS1864_MIN_KEYGEN_STRENGTH 112

/*
 * Generate probable primes 'p' & 'q'. See FIPS 186-4 Section B.3.6
 * "Generation of Probable Primes with Conditions Based on Auxiliary Probable
 * Primes".
 *
 * Params:
 *     rsa  Object used to store primes p & q.
 *     test Object used for CAVS testing only.that contains..
 *       p1, p2 The returned auxiliary primes for p.
 *              If NULL they are not returned.
 *       Xpout An optionally returned random number used during generation of p.
 *       Xp An optional passed in value (that is random number used during
 *          generation of p).
 *       Xp1, Xp2 Optionally passed in randomly generated numbers from which
 *                auxiliary primes p1 & p2 are calculated. If NULL these values
 *                are generated internally.
 *       q1, q2 The returned auxiliary primes for q.
 *              If NULL they are not returned.
 *       Xqout An optionally returned random number used during generation of q.
 *       Xq An optional passed in value (that is random number used during
 *          generation of q).
 *       Xq1, Xq2 Optionally passed in randomly generated numbers from which
 *                auxiliary primes q1 & q2 are calculated. If NULL these values
 *                are generated internally.
 *     nbits The key size in bits (The size of the modulus n).
 *     e The public exponent.
 *     ctx A BN_CTX object.
 *     cb An optional BIGNUM callback.
 * Returns: 1 if successful, or  0 otherwise.
 * Notes:
 *     p1, p2, q1, q2, Xpout, Xqout are returned if they are not NULL.
 *     Xp, Xp1, Xp2, Xq, Xq1, Xq2 are optionally passed in.
 *     (Required for CAVS testing).
 */
int ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test,
                                       int nbits, const BIGNUM *e, BN_CTX *ctx,
                                       BN_GENCB *cb)
{
    int ret = 0, ok;
    /* Temp allocated BIGNUMS */
    BIGNUM *Xpo = NULL, *Xqo = NULL, *tmp = NULL;
    /* Intermediate BIGNUMS that can be returned for testing */
    BIGNUM *p1 = NULL, *p2 = NULL;
    BIGNUM *q1 = NULL, *q2 = NULL;
    /* Intermediate BIGNUMS that can be input for testing */
    BIGNUM *Xpout = NULL, *Xqout = NULL;
    BIGNUM *Xp = NULL, *Xp1 = NULL, *Xp2 = NULL;
    BIGNUM *Xq = NULL, *Xq1 = NULL, *Xq2 = NULL;

#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
    if (test != NULL) {
        Xp1 = test->Xp1;
        Xp2 = test->Xp2;
        Xq1 = test->Xq1;
        Xq2 = test->Xq2;
        Xp = test->Xp;
        Xq = test->Xq;
        p1 = test->p1;
        p2 = test->p2;
        q1 = test->q1;
        q2 = test->q2;
    }
#endif

    /* (Step 1) Check key length
     * NOTE: SP800-131A Rev1 Disallows key lengths of < 2048 bits for RSA
     * Signature Generation and Key Agree/Transport.
     */
    if (nbits < RSA_FIPS1864_MIN_KEYGEN_KEYSIZE) {
        ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL);
        return 0;
    }

    if (!ossl_rsa_check_public_exponent(e)) {
        ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE);
        return 0;
    }

    /* (Step 3) Determine strength and check rand generator strength is ok -
     * this step is redundant because the generator always returns a higher
     * strength than is required.
     */

    BN_CTX_start(ctx);
    tmp = BN_CTX_get(ctx);
    Xpo = (Xpout != NULL) ? Xpout : BN_CTX_get(ctx);
    Xqo = (Xqout != NULL) ? Xqout : BN_CTX_get(ctx);
    if (tmp == NULL || Xpo == NULL || Xqo == NULL)
        goto err;
    BN_set_flags(Xpo, BN_FLG_CONSTTIME);
    BN_set_flags(Xqo, BN_FLG_CONSTTIME);

    if (rsa->p == NULL)
        rsa->p = BN_secure_new();
    if (rsa->q == NULL)
        rsa->q = BN_secure_new();
    if (rsa->p == NULL || rsa->q == NULL)
        goto err;
    BN_set_flags(rsa->p, BN_FLG_CONSTTIME);
    BN_set_flags(rsa->q, BN_FLG_CONSTTIME);

    /* (Step 4) Generate p, Xp */
    if (!ossl_bn_rsa_fips186_4_gen_prob_primes(rsa->p, Xpo, p1, p2, Xp, Xp1, Xp2,
                                               nbits, e, ctx, cb))
        goto err;
    for (;;) {
        /* (Step 5) Generate q, Xq*/
        if (!ossl_bn_rsa_fips186_4_gen_prob_primes(rsa->q, Xqo, q1, q2, Xq, Xq1,
                                                   Xq2, nbits, e, ctx, cb))
            goto err;

        /* (Step 6) |Xp - Xq| > 2^(nbitlen/2 - 100) */
        ok = ossl_rsa_check_pminusq_diff(tmp, Xpo, Xqo, nbits);
        if (ok < 0)
            goto err;
        if (ok == 0)
            continue;

        /* (Step 6) |p - q| > 2^(nbitlen/2 - 100) */
        ok = ossl_rsa_check_pminusq_diff(tmp, rsa->p, rsa->q, nbits);
        if (ok < 0)
            goto err;
        if (ok == 0)
            continue;
        break; /* successfully finished */
    }
    rsa->dirty_cnt++;
    ret = 1;
err:
    /* Zeroize any internally generated values that are not returned */
    if (Xpo != Xpout)
        BN_clear(Xpo);
    if (Xqo != Xqout)
        BN_clear(Xqo);
    BN_clear(tmp);

    BN_CTX_end(ctx);
    return ret;
}

/*
 * Validates the RSA key size based on the target strength.
 * See SP800-56Br1 6.3.1.1 (Steps 1a-1b)
 *
 * Params:
 *     nbits The key size in bits.
 *     strength The target strength in bits. -1 means the target
 *              strength is unknown.
 * Returns: 1 if the key size matches the target strength, or 0 otherwise.
 */
int ossl_rsa_sp800_56b_validate_strength(int nbits, int strength)
{
    int s = (int)ossl_ifc_ffc_compute_security_bits(nbits);

#ifdef FIPS_MODULE
    if (s < RSA_FIPS1864_MIN_KEYGEN_STRENGTH) {
        ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS);
        return 0;
    }
#endif
    if (strength != -1 && s != strength) {
        ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_STRENGTH);
        return 0;
    }
    return 1;
}

/*
 * Validate that the random bit generator is of sufficient strength to generate
 * a key of the specified length.
 */
static int rsa_validate_rng_strength(EVP_RAND_CTX *rng, int nbits)
{
    if (rng == NULL)
        return 0;
#ifdef FIPS_MODULE
    /*
     * This should become mainstream once similar tests are added to the other
     * key generations and once there is a way to disable these checks.
     */
    if (EVP_RAND_get_strength(rng) < ossl_ifc_ffc_compute_security_bits(nbits)) {
        ERR_raise(ERR_LIB_RSA,
                  RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT);
        return 0;
    }
#endif
    return 1;
}

/*
 *
 * Using p & q, calculate other required parameters such as n, d.
 * as well as the CRT parameters dP, dQ, qInv.
 *
 * See SP800-56Br1
 *   6.3.1.1 rsakpg1 - basic (Steps 3-4)
 *   6.3.1.3 rsakpg1 - crt   (Step 5)
 *
 * Params:
 *     rsa An rsa object.
 *     nbits The key size.
 *     e The public exponent.
 *     ctx A BN_CTX object.
 * Notes:
 *   There is a small chance that the generated d will be too small.
 * Returns: -1 = error,
 *           0 = d is too small,
 *           1 = success.
 */
int ossl_rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits,
                                             const BIGNUM *e, BN_CTX *ctx)
{
    int ret = -1;
    BIGNUM *p1, *q1, *lcm, *p1q1, *gcd;

    BN_CTX_start(ctx);
    p1 = BN_CTX_get(ctx);
    q1 = BN_CTX_get(ctx);
    lcm = BN_CTX_get(ctx);
    p1q1 = BN_CTX_get(ctx);
    gcd = BN_CTX_get(ctx);
    if (gcd == NULL)
        goto err;

    BN_set_flags(p1, BN_FLG_CONSTTIME);
    BN_set_flags(q1, BN_FLG_CONSTTIME);
    BN_set_flags(lcm, BN_FLG_CONSTTIME);
    BN_set_flags(p1q1, BN_FLG_CONSTTIME);
    BN_set_flags(gcd, BN_FLG_CONSTTIME);

    /* LCM((p-1, q-1)) */
    if (ossl_rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, p1q1) != 1)
        goto err;

    /* copy e */
    BN_free(rsa->e);
    rsa->e = BN_dup(e);
    if (rsa->e == NULL)
        goto err;

    BN_clear_free(rsa->d);
    /* (Step 3) d = (e^-1) mod (LCM(p-1, q-1)) */
    rsa->d = BN_secure_new();
    if (rsa->d == NULL)
        goto err;
    BN_set_flags(rsa->d, BN_FLG_CONSTTIME);
    if (BN_mod_inverse(rsa->d, e, lcm, ctx) == NULL)
        goto err;

    /* (Step 3) return an error if d is too small */
    if (BN_num_bits(rsa->d) <= (nbits >> 1)) {
        ret = 0;
        goto err;
    }

    /* (Step 4) n = pq */
    if (rsa->n == NULL)
        rsa->n = BN_new();
    if (rsa->n == NULL || !BN_mul(rsa->n, rsa->p, rsa->q, ctx))
        goto err;

    /* (Step 5a) dP = d mod (p-1) */
    if (rsa->dmp1 == NULL)
        rsa->dmp1 = BN_secure_new();
    if (rsa->dmp1 == NULL)
        goto err;
    BN_set_flags(rsa->dmp1, BN_FLG_CONSTTIME);
    if (!BN_mod(rsa->dmp1, rsa->d, p1, ctx))
        goto err;

    /* (Step 5b) dQ = d mod (q-1) */
    if (rsa->dmq1 == NULL)
        rsa->dmq1 = BN_secure_new();
    if (rsa->dmq1 == NULL)
        goto err;
    BN_set_flags(rsa->dmq1, BN_FLG_CONSTTIME);
    if (!BN_mod(rsa->dmq1, rsa->d, q1, ctx))
        goto err;

    /* (Step 5c) qInv = (inverse of q) mod p */
    BN_free(rsa->iqmp);
    rsa->iqmp = BN_secure_new();
    if (rsa->iqmp == NULL)
        goto err;
    BN_set_flags(rsa->iqmp, BN_FLG_CONSTTIME);
    if (BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx) == NULL)
        goto err;

    rsa->dirty_cnt++;
    ret = 1;
err:
    if (ret != 1) {
        BN_free(rsa->e);
        rsa->e = NULL;
        BN_free(rsa->d);
        rsa->d = NULL;
        BN_free(rsa->n);
        rsa->n = NULL;
        BN_free(rsa->iqmp);
        rsa->iqmp = NULL;
        BN_free(rsa->dmq1);
        rsa->dmq1 = NULL;
        BN_free(rsa->dmp1);
        rsa->dmp1 = NULL;
    }
    BN_clear(p1);
    BN_clear(q1);
    BN_clear(lcm);
    BN_clear(p1q1);
    BN_clear(gcd);

    BN_CTX_end(ctx);
    return ret;
}

/*
 * Generate a SP800-56B RSA key.
 *
 * See SP800-56Br1 6.3.1 "RSA Key-Pair Generation with a Fixed Public Exponent"
 *    6.3.1.1 rsakpg1 - basic
 *    6.3.1.3 rsakpg1 - crt
 *
 * See also FIPS 186-4 Section B.3.6
 * "Generation of Probable Primes with Conditions Based on Auxiliary
 * Probable Primes."
 *
 * Params:
 *     rsa The rsa object.
 *     nbits The intended key size in bits.
 *     efixed The public exponent. If NULL a default of 65537 is used.
 *     cb An optional BIGNUM callback.
 * Returns: 1 if successfully generated otherwise it returns 0.
 */
int ossl_rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed,
                                    BN_GENCB *cb)
{
    int ret = 0;
    int ok;
    BN_CTX *ctx = NULL;
    BIGNUM *e = NULL;
    RSA_ACVP_TEST *info = NULL;

#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
    info = rsa->acvp_test;
#endif

    /* (Steps 1a-1b) : Currently ignores the strength check */
    if (!ossl_rsa_sp800_56b_validate_strength(nbits, -1))
        return 0;

    /* Check that the RNG is capable of generating a key this large */
   if (!rsa_validate_rng_strength(RAND_get0_private(rsa->libctx), nbits))
        return 0;

    ctx = BN_CTX_new_ex(rsa->libctx);
    if (ctx == NULL)
        return 0;

    /* Set default if e is not passed in */
    if (efixed == NULL) {
        e = BN_new();
        if (e == NULL || !BN_set_word(e, 65537))
            goto err;
    } else {
        e = (BIGNUM *)efixed;
    }
    /* (Step 1c) fixed exponent is checked later .*/

    for (;;) {
        /* (Step 2) Generate prime factors */
        if (!ossl_rsa_fips186_4_gen_prob_primes(rsa, info, nbits, e, ctx, cb))
            goto err;
        /* (Steps 3-5) Compute params d, n, dP, dQ, qInv */
        ok = ossl_rsa_sp800_56b_derive_params_from_pq(rsa, nbits, e, ctx);
        if (ok < 0)
            goto err;
        if (ok > 0)
            break;
        /* Gets here if computed d is too small - so try again */
    }

    /* (Step 6) Do pairwise test - optional validity test has been omitted */
    ret = ossl_rsa_sp800_56b_pairwise_test(rsa, ctx);
err:
    if (efixed == NULL)
        BN_free(e);
    BN_CTX_free(ctx);
    return ret;
}

/*
 * See SP800-56Br1 6.3.1.3 (Step 6) Perform a pair-wise consistency test by
 * verifying that: k = (k^e)^d mod n for some integer k where 1 < k < n-1.
 *
 * Returns 1 if the RSA key passes the pairwise test or 0 it it fails.
 */
int ossl_rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx)
{
    int ret = 0;
    BIGNUM *k, *tmp;

    BN_CTX_start(ctx);
    tmp = BN_CTX_get(ctx);
    k = BN_CTX_get(ctx);
    if (k == NULL)
        goto err;
    BN_set_flags(k, BN_FLG_CONSTTIME);

    ret = (BN_set_word(k, 2)
           && BN_mod_exp(tmp, k, rsa->e, rsa->n, ctx)
           && BN_mod_exp(tmp, tmp, rsa->d, rsa->n, ctx)
           && BN_cmp(k, tmp) == 0);
    if (ret == 0)
        ERR_raise(ERR_LIB_RSA, RSA_R_PAIRWISE_TEST_FAILURE);
err:
    BN_CTX_end(ctx);
    return ret;
}
