1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2018-2023 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. 4e1051a39Sopenharmony_ci * 5e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 6e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 7e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 8e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 9e1051a39Sopenharmony_ci */ 10e1051a39Sopenharmony_ci 11e1051a39Sopenharmony_ci#include <openssl/err.h> 12e1051a39Sopenharmony_ci#include <openssl/bn.h> 13e1051a39Sopenharmony_ci#include <openssl/core.h> 14e1051a39Sopenharmony_ci#include <openssl/evp.h> 15e1051a39Sopenharmony_ci#include <openssl/rand.h> 16e1051a39Sopenharmony_ci#include "crypto/bn.h" 17e1051a39Sopenharmony_ci#include "crypto/security_bits.h" 18e1051a39Sopenharmony_ci#include "rsa_local.h" 19e1051a39Sopenharmony_ci 20e1051a39Sopenharmony_ci#define RSA_FIPS1864_MIN_KEYGEN_KEYSIZE 2048 21e1051a39Sopenharmony_ci#define RSA_FIPS1864_MIN_KEYGEN_STRENGTH 112 22e1051a39Sopenharmony_ci 23e1051a39Sopenharmony_ci/* 24e1051a39Sopenharmony_ci * Generate probable primes 'p' & 'q'. See FIPS 186-4 Section B.3.6 25e1051a39Sopenharmony_ci * "Generation of Probable Primes with Conditions Based on Auxiliary Probable 26e1051a39Sopenharmony_ci * Primes". 27e1051a39Sopenharmony_ci * 28e1051a39Sopenharmony_ci * Params: 29e1051a39Sopenharmony_ci * rsa Object used to store primes p & q. 30e1051a39Sopenharmony_ci * test Object used for CAVS testing only.that contains.. 31e1051a39Sopenharmony_ci * p1, p2 The returned auxiliary primes for p. 32e1051a39Sopenharmony_ci * If NULL they are not returned. 33e1051a39Sopenharmony_ci * Xpout An optionally returned random number used during generation of p. 34e1051a39Sopenharmony_ci * Xp An optional passed in value (that is random number used during 35e1051a39Sopenharmony_ci * generation of p). 36e1051a39Sopenharmony_ci * Xp1, Xp2 Optionally passed in randomly generated numbers from which 37e1051a39Sopenharmony_ci * auxiliary primes p1 & p2 are calculated. If NULL these values 38e1051a39Sopenharmony_ci * are generated internally. 39e1051a39Sopenharmony_ci * q1, q2 The returned auxiliary primes for q. 40e1051a39Sopenharmony_ci * If NULL they are not returned. 41e1051a39Sopenharmony_ci * Xqout An optionally returned random number used during generation of q. 42e1051a39Sopenharmony_ci * Xq An optional passed in value (that is random number used during 43e1051a39Sopenharmony_ci * generation of q). 44e1051a39Sopenharmony_ci * Xq1, Xq2 Optionally passed in randomly generated numbers from which 45e1051a39Sopenharmony_ci * auxiliary primes q1 & q2 are calculated. If NULL these values 46e1051a39Sopenharmony_ci * are generated internally. 47e1051a39Sopenharmony_ci * nbits The key size in bits (The size of the modulus n). 48e1051a39Sopenharmony_ci * e The public exponent. 49e1051a39Sopenharmony_ci * ctx A BN_CTX object. 50e1051a39Sopenharmony_ci * cb An optional BIGNUM callback. 51e1051a39Sopenharmony_ci * Returns: 1 if successful, or 0 otherwise. 52e1051a39Sopenharmony_ci * Notes: 53e1051a39Sopenharmony_ci * p1, p2, q1, q2, Xpout, Xqout are returned if they are not NULL. 54e1051a39Sopenharmony_ci * Xp, Xp1, Xp2, Xq, Xq1, Xq2 are optionally passed in. 55e1051a39Sopenharmony_ci * (Required for CAVS testing). 56e1051a39Sopenharmony_ci */ 57e1051a39Sopenharmony_ciint ossl_rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, 58e1051a39Sopenharmony_ci int nbits, const BIGNUM *e, BN_CTX *ctx, 59e1051a39Sopenharmony_ci BN_GENCB *cb) 60e1051a39Sopenharmony_ci{ 61e1051a39Sopenharmony_ci int ret = 0, ok; 62e1051a39Sopenharmony_ci /* Temp allocated BIGNUMS */ 63e1051a39Sopenharmony_ci BIGNUM *Xpo = NULL, *Xqo = NULL, *tmp = NULL; 64e1051a39Sopenharmony_ci /* Intermediate BIGNUMS that can be returned for testing */ 65e1051a39Sopenharmony_ci BIGNUM *p1 = NULL, *p2 = NULL; 66e1051a39Sopenharmony_ci BIGNUM *q1 = NULL, *q2 = NULL; 67e1051a39Sopenharmony_ci /* Intermediate BIGNUMS that can be input for testing */ 68e1051a39Sopenharmony_ci BIGNUM *Xpout = NULL, *Xqout = NULL; 69e1051a39Sopenharmony_ci BIGNUM *Xp = NULL, *Xp1 = NULL, *Xp2 = NULL; 70e1051a39Sopenharmony_ci BIGNUM *Xq = NULL, *Xq1 = NULL, *Xq2 = NULL; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) 73e1051a39Sopenharmony_ci if (test != NULL) { 74e1051a39Sopenharmony_ci Xp1 = test->Xp1; 75e1051a39Sopenharmony_ci Xp2 = test->Xp2; 76e1051a39Sopenharmony_ci Xq1 = test->Xq1; 77e1051a39Sopenharmony_ci Xq2 = test->Xq2; 78e1051a39Sopenharmony_ci Xp = test->Xp; 79e1051a39Sopenharmony_ci Xq = test->Xq; 80e1051a39Sopenharmony_ci p1 = test->p1; 81e1051a39Sopenharmony_ci p2 = test->p2; 82e1051a39Sopenharmony_ci q1 = test->q1; 83e1051a39Sopenharmony_ci q2 = test->q2; 84e1051a39Sopenharmony_ci } 85e1051a39Sopenharmony_ci#endif 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_ci /* (Step 1) Check key length 88e1051a39Sopenharmony_ci * NOTE: SP800-131A Rev1 Disallows key lengths of < 2048 bits for RSA 89e1051a39Sopenharmony_ci * Signature Generation and Key Agree/Transport. 90e1051a39Sopenharmony_ci */ 91e1051a39Sopenharmony_ci if (nbits < RSA_FIPS1864_MIN_KEYGEN_KEYSIZE) { 92e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL); 93e1051a39Sopenharmony_ci return 0; 94e1051a39Sopenharmony_ci } 95e1051a39Sopenharmony_ci 96e1051a39Sopenharmony_ci if (!ossl_rsa_check_public_exponent(e)) { 97e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); 98e1051a39Sopenharmony_ci return 0; 99e1051a39Sopenharmony_ci } 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci /* (Step 3) Determine strength and check rand generator strength is ok - 102e1051a39Sopenharmony_ci * this step is redundant because the generator always returns a higher 103e1051a39Sopenharmony_ci * strength than is required. 104e1051a39Sopenharmony_ci */ 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci BN_CTX_start(ctx); 107e1051a39Sopenharmony_ci tmp = BN_CTX_get(ctx); 108e1051a39Sopenharmony_ci Xpo = (Xpout != NULL) ? Xpout : BN_CTX_get(ctx); 109e1051a39Sopenharmony_ci Xqo = (Xqout != NULL) ? Xqout : BN_CTX_get(ctx); 110e1051a39Sopenharmony_ci if (tmp == NULL || Xpo == NULL || Xqo == NULL) 111e1051a39Sopenharmony_ci goto err; 112e1051a39Sopenharmony_ci BN_set_flags(Xpo, BN_FLG_CONSTTIME); 113e1051a39Sopenharmony_ci BN_set_flags(Xqo, BN_FLG_CONSTTIME); 114e1051a39Sopenharmony_ci 115e1051a39Sopenharmony_ci if (rsa->p == NULL) 116e1051a39Sopenharmony_ci rsa->p = BN_secure_new(); 117e1051a39Sopenharmony_ci if (rsa->q == NULL) 118e1051a39Sopenharmony_ci rsa->q = BN_secure_new(); 119e1051a39Sopenharmony_ci if (rsa->p == NULL || rsa->q == NULL) 120e1051a39Sopenharmony_ci goto err; 121e1051a39Sopenharmony_ci BN_set_flags(rsa->p, BN_FLG_CONSTTIME); 122e1051a39Sopenharmony_ci BN_set_flags(rsa->q, BN_FLG_CONSTTIME); 123e1051a39Sopenharmony_ci 124e1051a39Sopenharmony_ci /* (Step 4) Generate p, Xp */ 125e1051a39Sopenharmony_ci if (!ossl_bn_rsa_fips186_4_gen_prob_primes(rsa->p, Xpo, p1, p2, Xp, Xp1, Xp2, 126e1051a39Sopenharmony_ci nbits, e, ctx, cb)) 127e1051a39Sopenharmony_ci goto err; 128e1051a39Sopenharmony_ci for(;;) { 129e1051a39Sopenharmony_ci /* (Step 5) Generate q, Xq*/ 130e1051a39Sopenharmony_ci if (!ossl_bn_rsa_fips186_4_gen_prob_primes(rsa->q, Xqo, q1, q2, Xq, Xq1, 131e1051a39Sopenharmony_ci Xq2, nbits, e, ctx, cb)) 132e1051a39Sopenharmony_ci goto err; 133e1051a39Sopenharmony_ci 134e1051a39Sopenharmony_ci /* (Step 6) |Xp - Xq| > 2^(nbitlen/2 - 100) */ 135e1051a39Sopenharmony_ci ok = ossl_rsa_check_pminusq_diff(tmp, Xpo, Xqo, nbits); 136e1051a39Sopenharmony_ci if (ok < 0) 137e1051a39Sopenharmony_ci goto err; 138e1051a39Sopenharmony_ci if (ok == 0) 139e1051a39Sopenharmony_ci continue; 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci /* (Step 6) |p - q| > 2^(nbitlen/2 - 100) */ 142e1051a39Sopenharmony_ci ok = ossl_rsa_check_pminusq_diff(tmp, rsa->p, rsa->q, nbits); 143e1051a39Sopenharmony_ci if (ok < 0) 144e1051a39Sopenharmony_ci goto err; 145e1051a39Sopenharmony_ci if (ok == 0) 146e1051a39Sopenharmony_ci continue; 147e1051a39Sopenharmony_ci break; /* successfully finished */ 148e1051a39Sopenharmony_ci } 149e1051a39Sopenharmony_ci rsa->dirty_cnt++; 150e1051a39Sopenharmony_ci ret = 1; 151e1051a39Sopenharmony_cierr: 152e1051a39Sopenharmony_ci /* Zeroize any internally generated values that are not returned */ 153e1051a39Sopenharmony_ci if (Xpo != Xpout) 154e1051a39Sopenharmony_ci BN_clear(Xpo); 155e1051a39Sopenharmony_ci if (Xqo != Xqout) 156e1051a39Sopenharmony_ci BN_clear(Xqo); 157e1051a39Sopenharmony_ci BN_clear(tmp); 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ci BN_CTX_end(ctx); 160e1051a39Sopenharmony_ci return ret; 161e1051a39Sopenharmony_ci} 162e1051a39Sopenharmony_ci 163e1051a39Sopenharmony_ci/* 164e1051a39Sopenharmony_ci * Validates the RSA key size based on the target strength. 165e1051a39Sopenharmony_ci * See SP800-56Br1 6.3.1.1 (Steps 1a-1b) 166e1051a39Sopenharmony_ci * 167e1051a39Sopenharmony_ci * Params: 168e1051a39Sopenharmony_ci * nbits The key size in bits. 169e1051a39Sopenharmony_ci * strength The target strength in bits. -1 means the target 170e1051a39Sopenharmony_ci * strength is unknown. 171e1051a39Sopenharmony_ci * Returns: 1 if the key size matches the target strength, or 0 otherwise. 172e1051a39Sopenharmony_ci */ 173e1051a39Sopenharmony_ciint ossl_rsa_sp800_56b_validate_strength(int nbits, int strength) 174e1051a39Sopenharmony_ci{ 175e1051a39Sopenharmony_ci int s = (int)ossl_ifc_ffc_compute_security_bits(nbits); 176e1051a39Sopenharmony_ci 177e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 178e1051a39Sopenharmony_ci if (s < RSA_FIPS1864_MIN_KEYGEN_STRENGTH) { 179e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS); 180e1051a39Sopenharmony_ci return 0; 181e1051a39Sopenharmony_ci } 182e1051a39Sopenharmony_ci#endif 183e1051a39Sopenharmony_ci if (strength != -1 && s != strength) { 184e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_STRENGTH); 185e1051a39Sopenharmony_ci return 0; 186e1051a39Sopenharmony_ci } 187e1051a39Sopenharmony_ci return 1; 188e1051a39Sopenharmony_ci} 189e1051a39Sopenharmony_ci 190e1051a39Sopenharmony_ci/* 191e1051a39Sopenharmony_ci * Validate that the random bit generator is of sufficient strength to generate 192e1051a39Sopenharmony_ci * a key of the specified length. 193e1051a39Sopenharmony_ci */ 194e1051a39Sopenharmony_cistatic int rsa_validate_rng_strength(EVP_RAND_CTX *rng, int nbits) 195e1051a39Sopenharmony_ci{ 196e1051a39Sopenharmony_ci if (rng == NULL) 197e1051a39Sopenharmony_ci return 0; 198e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 199e1051a39Sopenharmony_ci /* 200e1051a39Sopenharmony_ci * This should become mainstream once similar tests are added to the other 201e1051a39Sopenharmony_ci * key generations and once there is a way to disable these checks. 202e1051a39Sopenharmony_ci */ 203e1051a39Sopenharmony_ci if (EVP_RAND_get_strength(rng) < ossl_ifc_ffc_compute_security_bits(nbits)) { 204e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, 205e1051a39Sopenharmony_ci RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT); 206e1051a39Sopenharmony_ci return 0; 207e1051a39Sopenharmony_ci } 208e1051a39Sopenharmony_ci#endif 209e1051a39Sopenharmony_ci return 1; 210e1051a39Sopenharmony_ci} 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_ci/* 213e1051a39Sopenharmony_ci * 214e1051a39Sopenharmony_ci * Using p & q, calculate other required parameters such as n, d. 215e1051a39Sopenharmony_ci * as well as the CRT parameters dP, dQ, qInv. 216e1051a39Sopenharmony_ci * 217e1051a39Sopenharmony_ci * See SP800-56Br1 218e1051a39Sopenharmony_ci * 6.3.1.1 rsakpg1 - basic (Steps 3-4) 219e1051a39Sopenharmony_ci * 6.3.1.3 rsakpg1 - crt (Step 5) 220e1051a39Sopenharmony_ci * 221e1051a39Sopenharmony_ci * Params: 222e1051a39Sopenharmony_ci * rsa An rsa object. 223e1051a39Sopenharmony_ci * nbits The key size. 224e1051a39Sopenharmony_ci * e The public exponent. 225e1051a39Sopenharmony_ci * ctx A BN_CTX object. 226e1051a39Sopenharmony_ci * Notes: 227e1051a39Sopenharmony_ci * There is a small chance that the generated d will be too small. 228e1051a39Sopenharmony_ci * Returns: -1 = error, 229e1051a39Sopenharmony_ci * 0 = d is too small, 230e1051a39Sopenharmony_ci * 1 = success. 231e1051a39Sopenharmony_ci */ 232e1051a39Sopenharmony_ciint ossl_rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits, 233e1051a39Sopenharmony_ci const BIGNUM *e, BN_CTX *ctx) 234e1051a39Sopenharmony_ci{ 235e1051a39Sopenharmony_ci int ret = -1; 236e1051a39Sopenharmony_ci BIGNUM *p1, *q1, *lcm, *p1q1, *gcd; 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_ci BN_CTX_start(ctx); 239e1051a39Sopenharmony_ci p1 = BN_CTX_get(ctx); 240e1051a39Sopenharmony_ci q1 = BN_CTX_get(ctx); 241e1051a39Sopenharmony_ci lcm = BN_CTX_get(ctx); 242e1051a39Sopenharmony_ci p1q1 = BN_CTX_get(ctx); 243e1051a39Sopenharmony_ci gcd = BN_CTX_get(ctx); 244e1051a39Sopenharmony_ci if (gcd == NULL) 245e1051a39Sopenharmony_ci goto err; 246e1051a39Sopenharmony_ci 247e1051a39Sopenharmony_ci BN_set_flags(p1, BN_FLG_CONSTTIME); 248e1051a39Sopenharmony_ci BN_set_flags(q1, BN_FLG_CONSTTIME); 249e1051a39Sopenharmony_ci BN_set_flags(lcm, BN_FLG_CONSTTIME); 250e1051a39Sopenharmony_ci BN_set_flags(p1q1, BN_FLG_CONSTTIME); 251e1051a39Sopenharmony_ci BN_set_flags(gcd, BN_FLG_CONSTTIME); 252e1051a39Sopenharmony_ci 253e1051a39Sopenharmony_ci /* LCM((p-1, q-1)) */ 254e1051a39Sopenharmony_ci if (ossl_rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, p1q1) != 1) 255e1051a39Sopenharmony_ci goto err; 256e1051a39Sopenharmony_ci 257e1051a39Sopenharmony_ci /* copy e */ 258e1051a39Sopenharmony_ci BN_free(rsa->e); 259e1051a39Sopenharmony_ci rsa->e = BN_dup(e); 260e1051a39Sopenharmony_ci if (rsa->e == NULL) 261e1051a39Sopenharmony_ci goto err; 262e1051a39Sopenharmony_ci 263e1051a39Sopenharmony_ci BN_clear_free(rsa->d); 264e1051a39Sopenharmony_ci /* (Step 3) d = (e^-1) mod (LCM(p-1, q-1)) */ 265e1051a39Sopenharmony_ci rsa->d = BN_secure_new(); 266e1051a39Sopenharmony_ci if (rsa->d == NULL) 267e1051a39Sopenharmony_ci goto err; 268e1051a39Sopenharmony_ci BN_set_flags(rsa->d, BN_FLG_CONSTTIME); 269e1051a39Sopenharmony_ci if (BN_mod_inverse(rsa->d, e, lcm, ctx) == NULL) 270e1051a39Sopenharmony_ci goto err; 271e1051a39Sopenharmony_ci 272e1051a39Sopenharmony_ci /* (Step 3) return an error if d is too small */ 273e1051a39Sopenharmony_ci if (BN_num_bits(rsa->d) <= (nbits >> 1)) { 274e1051a39Sopenharmony_ci ret = 0; 275e1051a39Sopenharmony_ci goto err; 276e1051a39Sopenharmony_ci } 277e1051a39Sopenharmony_ci 278e1051a39Sopenharmony_ci /* (Step 4) n = pq */ 279e1051a39Sopenharmony_ci if (rsa->n == NULL) 280e1051a39Sopenharmony_ci rsa->n = BN_new(); 281e1051a39Sopenharmony_ci if (rsa->n == NULL || !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) 282e1051a39Sopenharmony_ci goto err; 283e1051a39Sopenharmony_ci 284e1051a39Sopenharmony_ci /* (Step 5a) dP = d mod (p-1) */ 285e1051a39Sopenharmony_ci if (rsa->dmp1 == NULL) 286e1051a39Sopenharmony_ci rsa->dmp1 = BN_secure_new(); 287e1051a39Sopenharmony_ci if (rsa->dmp1 == NULL) 288e1051a39Sopenharmony_ci goto err; 289e1051a39Sopenharmony_ci BN_set_flags(rsa->dmp1, BN_FLG_CONSTTIME); 290e1051a39Sopenharmony_ci if (!BN_mod(rsa->dmp1, rsa->d, p1, ctx)) 291e1051a39Sopenharmony_ci goto err; 292e1051a39Sopenharmony_ci 293e1051a39Sopenharmony_ci /* (Step 5b) dQ = d mod (q-1) */ 294e1051a39Sopenharmony_ci if (rsa->dmq1 == NULL) 295e1051a39Sopenharmony_ci rsa->dmq1 = BN_secure_new(); 296e1051a39Sopenharmony_ci if (rsa->dmq1 == NULL) 297e1051a39Sopenharmony_ci goto err; 298e1051a39Sopenharmony_ci BN_set_flags(rsa->dmq1, BN_FLG_CONSTTIME); 299e1051a39Sopenharmony_ci if (!BN_mod(rsa->dmq1, rsa->d, q1, ctx)) 300e1051a39Sopenharmony_ci goto err; 301e1051a39Sopenharmony_ci 302e1051a39Sopenharmony_ci /* (Step 5c) qInv = (inverse of q) mod p */ 303e1051a39Sopenharmony_ci BN_free(rsa->iqmp); 304e1051a39Sopenharmony_ci rsa->iqmp = BN_secure_new(); 305e1051a39Sopenharmony_ci if (rsa->iqmp == NULL) 306e1051a39Sopenharmony_ci goto err; 307e1051a39Sopenharmony_ci BN_set_flags(rsa->iqmp, BN_FLG_CONSTTIME); 308e1051a39Sopenharmony_ci if (BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx) == NULL) 309e1051a39Sopenharmony_ci goto err; 310e1051a39Sopenharmony_ci 311e1051a39Sopenharmony_ci rsa->dirty_cnt++; 312e1051a39Sopenharmony_ci ret = 1; 313e1051a39Sopenharmony_cierr: 314e1051a39Sopenharmony_ci if (ret != 1) { 315e1051a39Sopenharmony_ci BN_free(rsa->e); 316e1051a39Sopenharmony_ci rsa->e = NULL; 317e1051a39Sopenharmony_ci BN_free(rsa->d); 318e1051a39Sopenharmony_ci rsa->d = NULL; 319e1051a39Sopenharmony_ci BN_free(rsa->n); 320e1051a39Sopenharmony_ci rsa->n = NULL; 321e1051a39Sopenharmony_ci BN_free(rsa->iqmp); 322e1051a39Sopenharmony_ci rsa->iqmp = NULL; 323e1051a39Sopenharmony_ci BN_free(rsa->dmq1); 324e1051a39Sopenharmony_ci rsa->dmq1 = NULL; 325e1051a39Sopenharmony_ci BN_free(rsa->dmp1); 326e1051a39Sopenharmony_ci rsa->dmp1 = NULL; 327e1051a39Sopenharmony_ci } 328e1051a39Sopenharmony_ci BN_clear(p1); 329e1051a39Sopenharmony_ci BN_clear(q1); 330e1051a39Sopenharmony_ci BN_clear(lcm); 331e1051a39Sopenharmony_ci BN_clear(p1q1); 332e1051a39Sopenharmony_ci BN_clear(gcd); 333e1051a39Sopenharmony_ci 334e1051a39Sopenharmony_ci BN_CTX_end(ctx); 335e1051a39Sopenharmony_ci return ret; 336e1051a39Sopenharmony_ci} 337e1051a39Sopenharmony_ci 338e1051a39Sopenharmony_ci/* 339e1051a39Sopenharmony_ci * Generate a SP800-56B RSA key. 340e1051a39Sopenharmony_ci * 341e1051a39Sopenharmony_ci * See SP800-56Br1 6.3.1 "RSA Key-Pair Generation with a Fixed Public Exponent" 342e1051a39Sopenharmony_ci * 6.3.1.1 rsakpg1 - basic 343e1051a39Sopenharmony_ci * 6.3.1.3 rsakpg1 - crt 344e1051a39Sopenharmony_ci * 345e1051a39Sopenharmony_ci * See also FIPS 186-4 Section B.3.6 346e1051a39Sopenharmony_ci * "Generation of Probable Primes with Conditions Based on Auxiliary 347e1051a39Sopenharmony_ci * Probable Primes." 348e1051a39Sopenharmony_ci * 349e1051a39Sopenharmony_ci * Params: 350e1051a39Sopenharmony_ci * rsa The rsa object. 351e1051a39Sopenharmony_ci * nbits The intended key size in bits. 352e1051a39Sopenharmony_ci * efixed The public exponent. If NULL a default of 65537 is used. 353e1051a39Sopenharmony_ci * cb An optional BIGNUM callback. 354e1051a39Sopenharmony_ci * Returns: 1 if successfully generated otherwise it returns 0. 355e1051a39Sopenharmony_ci */ 356e1051a39Sopenharmony_ciint ossl_rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed, 357e1051a39Sopenharmony_ci BN_GENCB *cb) 358e1051a39Sopenharmony_ci{ 359e1051a39Sopenharmony_ci int ret = 0; 360e1051a39Sopenharmony_ci int ok; 361e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 362e1051a39Sopenharmony_ci BIGNUM *e = NULL; 363e1051a39Sopenharmony_ci RSA_ACVP_TEST *info = NULL; 364e1051a39Sopenharmony_ci BIGNUM *tmp; 365e1051a39Sopenharmony_ci 366e1051a39Sopenharmony_ci#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) 367e1051a39Sopenharmony_ci info = rsa->acvp_test; 368e1051a39Sopenharmony_ci#endif 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_ci /* (Steps 1a-1b) : Currently ignores the strength check */ 371e1051a39Sopenharmony_ci if (!ossl_rsa_sp800_56b_validate_strength(nbits, -1)) 372e1051a39Sopenharmony_ci return 0; 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci /* Check that the RNG is capable of generating a key this large */ 375e1051a39Sopenharmony_ci if (!rsa_validate_rng_strength(RAND_get0_private(rsa->libctx), nbits)) 376e1051a39Sopenharmony_ci return 0; 377e1051a39Sopenharmony_ci 378e1051a39Sopenharmony_ci ctx = BN_CTX_new_ex(rsa->libctx); 379e1051a39Sopenharmony_ci if (ctx == NULL) 380e1051a39Sopenharmony_ci return 0; 381e1051a39Sopenharmony_ci 382e1051a39Sopenharmony_ci /* Set default if e is not passed in */ 383e1051a39Sopenharmony_ci if (efixed == NULL) { 384e1051a39Sopenharmony_ci e = BN_new(); 385e1051a39Sopenharmony_ci if (e == NULL || !BN_set_word(e, 65537)) 386e1051a39Sopenharmony_ci goto err; 387e1051a39Sopenharmony_ci } else { 388e1051a39Sopenharmony_ci e = (BIGNUM *)efixed; 389e1051a39Sopenharmony_ci } 390e1051a39Sopenharmony_ci /* (Step 1c) fixed exponent is checked later .*/ 391e1051a39Sopenharmony_ci 392e1051a39Sopenharmony_ci for (;;) { 393e1051a39Sopenharmony_ci /* (Step 2) Generate prime factors */ 394e1051a39Sopenharmony_ci if (!ossl_rsa_fips186_4_gen_prob_primes(rsa, info, nbits, e, ctx, cb)) 395e1051a39Sopenharmony_ci goto err; 396e1051a39Sopenharmony_ci 397e1051a39Sopenharmony_ci /* p>q check and skipping in case of acvp test */ 398e1051a39Sopenharmony_ci if (info == NULL && BN_cmp(rsa->p, rsa->q) < 0) { 399e1051a39Sopenharmony_ci tmp = rsa->p; 400e1051a39Sopenharmony_ci rsa->p = rsa->q; 401e1051a39Sopenharmony_ci rsa->q = tmp; 402e1051a39Sopenharmony_ci } 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_ci /* (Steps 3-5) Compute params d, n, dP, dQ, qInv */ 405e1051a39Sopenharmony_ci ok = ossl_rsa_sp800_56b_derive_params_from_pq(rsa, nbits, e, ctx); 406e1051a39Sopenharmony_ci if (ok < 0) 407e1051a39Sopenharmony_ci goto err; 408e1051a39Sopenharmony_ci if (ok > 0) 409e1051a39Sopenharmony_ci break; 410e1051a39Sopenharmony_ci /* Gets here if computed d is too small - so try again */ 411e1051a39Sopenharmony_ci } 412e1051a39Sopenharmony_ci 413e1051a39Sopenharmony_ci /* (Step 6) Do pairwise test - optional validity test has been omitted */ 414e1051a39Sopenharmony_ci ret = ossl_rsa_sp800_56b_pairwise_test(rsa, ctx); 415e1051a39Sopenharmony_cierr: 416e1051a39Sopenharmony_ci if (efixed == NULL) 417e1051a39Sopenharmony_ci BN_free(e); 418e1051a39Sopenharmony_ci BN_CTX_free(ctx); 419e1051a39Sopenharmony_ci return ret; 420e1051a39Sopenharmony_ci} 421e1051a39Sopenharmony_ci 422e1051a39Sopenharmony_ci/* 423e1051a39Sopenharmony_ci * See SP800-56Br1 6.3.1.3 (Step 6) Perform a pair-wise consistency test by 424e1051a39Sopenharmony_ci * verifying that: k = (k^e)^d mod n for some integer k where 1 < k < n-1. 425e1051a39Sopenharmony_ci * 426e1051a39Sopenharmony_ci * Returns 1 if the RSA key passes the pairwise test or 0 it it fails. 427e1051a39Sopenharmony_ci */ 428e1051a39Sopenharmony_ciint ossl_rsa_sp800_56b_pairwise_test(RSA *rsa, BN_CTX *ctx) 429e1051a39Sopenharmony_ci{ 430e1051a39Sopenharmony_ci int ret = 0; 431e1051a39Sopenharmony_ci BIGNUM *k, *tmp; 432e1051a39Sopenharmony_ci 433e1051a39Sopenharmony_ci BN_CTX_start(ctx); 434e1051a39Sopenharmony_ci tmp = BN_CTX_get(ctx); 435e1051a39Sopenharmony_ci k = BN_CTX_get(ctx); 436e1051a39Sopenharmony_ci if (k == NULL) 437e1051a39Sopenharmony_ci goto err; 438e1051a39Sopenharmony_ci BN_set_flags(k, BN_FLG_CONSTTIME); 439e1051a39Sopenharmony_ci 440e1051a39Sopenharmony_ci ret = (BN_set_word(k, 2) 441e1051a39Sopenharmony_ci && BN_mod_exp(tmp, k, rsa->e, rsa->n, ctx) 442e1051a39Sopenharmony_ci && BN_mod_exp(tmp, tmp, rsa->d, rsa->n, ctx) 443e1051a39Sopenharmony_ci && BN_cmp(k, tmp) == 0); 444e1051a39Sopenharmony_ci if (ret == 0) 445e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_PAIRWISE_TEST_FAILURE); 446e1051a39Sopenharmony_cierr: 447e1051a39Sopenharmony_ci BN_CTX_end(ctx); 448e1051a39Sopenharmony_ci return ret; 449e1051a39Sopenharmony_ci} 450