1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2018-2021 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 "crypto/bn.h" 14e1051a39Sopenharmony_ci#include "rsa_local.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci/* 17e1051a39Sopenharmony_ci * Part of the RSA keypair test. 18e1051a39Sopenharmony_ci * Check the Chinese Remainder Theorem components are valid. 19e1051a39Sopenharmony_ci * 20e1051a39Sopenharmony_ci * See SP800-5bBr1 21e1051a39Sopenharmony_ci * 6.4.1.2.3: rsakpv1-crt Step 7 22e1051a39Sopenharmony_ci * 6.4.1.3.3: rsakpv2-crt Step 7 23e1051a39Sopenharmony_ci */ 24e1051a39Sopenharmony_ciint ossl_rsa_check_crt_components(const RSA *rsa, BN_CTX *ctx) 25e1051a39Sopenharmony_ci{ 26e1051a39Sopenharmony_ci int ret = 0; 27e1051a39Sopenharmony_ci BIGNUM *r = NULL, *p1 = NULL, *q1 = NULL; 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ci /* check if only some of the crt components are set */ 30e1051a39Sopenharmony_ci if (rsa->dmp1 == NULL || rsa->dmq1 == NULL || rsa->iqmp == NULL) { 31e1051a39Sopenharmony_ci if (rsa->dmp1 != NULL || rsa->dmq1 != NULL || rsa->iqmp != NULL) 32e1051a39Sopenharmony_ci return 0; 33e1051a39Sopenharmony_ci return 1; /* return ok if all components are NULL */ 34e1051a39Sopenharmony_ci } 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_ci BN_CTX_start(ctx); 37e1051a39Sopenharmony_ci r = BN_CTX_get(ctx); 38e1051a39Sopenharmony_ci p1 = BN_CTX_get(ctx); 39e1051a39Sopenharmony_ci q1 = BN_CTX_get(ctx); 40e1051a39Sopenharmony_ci if (q1 != NULL) { 41e1051a39Sopenharmony_ci BN_set_flags(r, BN_FLG_CONSTTIME); 42e1051a39Sopenharmony_ci BN_set_flags(p1, BN_FLG_CONSTTIME); 43e1051a39Sopenharmony_ci BN_set_flags(q1, BN_FLG_CONSTTIME); 44e1051a39Sopenharmony_ci ret = 1; 45e1051a39Sopenharmony_ci } else { 46e1051a39Sopenharmony_ci ret = 0; 47e1051a39Sopenharmony_ci } 48e1051a39Sopenharmony_ci ret = ret 49e1051a39Sopenharmony_ci /* p1 = p -1 */ 50e1051a39Sopenharmony_ci && (BN_copy(p1, rsa->p) != NULL) 51e1051a39Sopenharmony_ci && BN_sub_word(p1, 1) 52e1051a39Sopenharmony_ci /* q1 = q - 1 */ 53e1051a39Sopenharmony_ci && (BN_copy(q1, rsa->q) != NULL) 54e1051a39Sopenharmony_ci && BN_sub_word(q1, 1) 55e1051a39Sopenharmony_ci /* (a) 1 < dP < (p – 1). */ 56e1051a39Sopenharmony_ci && (BN_cmp(rsa->dmp1, BN_value_one()) > 0) 57e1051a39Sopenharmony_ci && (BN_cmp(rsa->dmp1, p1) < 0) 58e1051a39Sopenharmony_ci /* (b) 1 < dQ < (q - 1). */ 59e1051a39Sopenharmony_ci && (BN_cmp(rsa->dmq1, BN_value_one()) > 0) 60e1051a39Sopenharmony_ci && (BN_cmp(rsa->dmq1, q1) < 0) 61e1051a39Sopenharmony_ci /* (c) 1 < qInv < p */ 62e1051a39Sopenharmony_ci && (BN_cmp(rsa->iqmp, BN_value_one()) > 0) 63e1051a39Sopenharmony_ci && (BN_cmp(rsa->iqmp, rsa->p) < 0) 64e1051a39Sopenharmony_ci /* (d) 1 = (dP . e) mod (p - 1)*/ 65e1051a39Sopenharmony_ci && BN_mod_mul(r, rsa->dmp1, rsa->e, p1, ctx) 66e1051a39Sopenharmony_ci && BN_is_one(r) 67e1051a39Sopenharmony_ci /* (e) 1 = (dQ . e) mod (q - 1) */ 68e1051a39Sopenharmony_ci && BN_mod_mul(r, rsa->dmq1, rsa->e, q1, ctx) 69e1051a39Sopenharmony_ci && BN_is_one(r) 70e1051a39Sopenharmony_ci /* (f) 1 = (qInv . q) mod p */ 71e1051a39Sopenharmony_ci && BN_mod_mul(r, rsa->iqmp, rsa->q, rsa->p, ctx) 72e1051a39Sopenharmony_ci && BN_is_one(r); 73e1051a39Sopenharmony_ci BN_clear(r); 74e1051a39Sopenharmony_ci BN_clear(p1); 75e1051a39Sopenharmony_ci BN_clear(q1); 76e1051a39Sopenharmony_ci BN_CTX_end(ctx); 77e1051a39Sopenharmony_ci return ret; 78e1051a39Sopenharmony_ci} 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci/* 81e1051a39Sopenharmony_ci * Part of the RSA keypair test. 82e1051a39Sopenharmony_ci * Check that (√2)(2^(nbits/2 - 1) <= p <= 2^(nbits/2) - 1 83e1051a39Sopenharmony_ci * 84e1051a39Sopenharmony_ci * See SP800-5bBr1 6.4.1.2.1 Part 5 (c) & (g) - used for both p and q. 85e1051a39Sopenharmony_ci * 86e1051a39Sopenharmony_ci * (√2)(2^(nbits/2 - 1) = (√2/2)(2^(nbits/2)) 87e1051a39Sopenharmony_ci */ 88e1051a39Sopenharmony_ciint ossl_rsa_check_prime_factor_range(const BIGNUM *p, int nbits, BN_CTX *ctx) 89e1051a39Sopenharmony_ci{ 90e1051a39Sopenharmony_ci int ret = 0; 91e1051a39Sopenharmony_ci BIGNUM *low; 92e1051a39Sopenharmony_ci int shift; 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ci nbits >>= 1; 95e1051a39Sopenharmony_ci shift = nbits - BN_num_bits(&ossl_bn_inv_sqrt_2); 96e1051a39Sopenharmony_ci 97e1051a39Sopenharmony_ci /* Upper bound check */ 98e1051a39Sopenharmony_ci if (BN_num_bits(p) != nbits) 99e1051a39Sopenharmony_ci return 0; 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci BN_CTX_start(ctx); 102e1051a39Sopenharmony_ci low = BN_CTX_get(ctx); 103e1051a39Sopenharmony_ci if (low == NULL) 104e1051a39Sopenharmony_ci goto err; 105e1051a39Sopenharmony_ci 106e1051a39Sopenharmony_ci /* set low = (√2)(2^(nbits/2 - 1) */ 107e1051a39Sopenharmony_ci if (!BN_copy(low, &ossl_bn_inv_sqrt_2)) 108e1051a39Sopenharmony_ci goto err; 109e1051a39Sopenharmony_ci 110e1051a39Sopenharmony_ci if (shift >= 0) { 111e1051a39Sopenharmony_ci /* 112e1051a39Sopenharmony_ci * We don't have all the bits. ossl_bn_inv_sqrt_2 contains a rounded up 113e1051a39Sopenharmony_ci * value, so there is a very low probability that we'll reject a valid 114e1051a39Sopenharmony_ci * value. 115e1051a39Sopenharmony_ci */ 116e1051a39Sopenharmony_ci if (!BN_lshift(low, low, shift)) 117e1051a39Sopenharmony_ci goto err; 118e1051a39Sopenharmony_ci } else if (!BN_rshift(low, low, -shift)) { 119e1051a39Sopenharmony_ci goto err; 120e1051a39Sopenharmony_ci } 121e1051a39Sopenharmony_ci if (BN_cmp(p, low) <= 0) 122e1051a39Sopenharmony_ci goto err; 123e1051a39Sopenharmony_ci ret = 1; 124e1051a39Sopenharmony_cierr: 125e1051a39Sopenharmony_ci BN_CTX_end(ctx); 126e1051a39Sopenharmony_ci return ret; 127e1051a39Sopenharmony_ci} 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci/* 130e1051a39Sopenharmony_ci * Part of the RSA keypair test. 131e1051a39Sopenharmony_ci * Check the prime factor (for either p or q) 132e1051a39Sopenharmony_ci * i.e: p is prime AND GCD(p - 1, e) = 1 133e1051a39Sopenharmony_ci * 134e1051a39Sopenharmony_ci * See SP800-56Br1 6.4.1.2.3 Step 5 (a to d) & (e to h). 135e1051a39Sopenharmony_ci */ 136e1051a39Sopenharmony_ciint ossl_rsa_check_prime_factor(BIGNUM *p, BIGNUM *e, int nbits, BN_CTX *ctx) 137e1051a39Sopenharmony_ci{ 138e1051a39Sopenharmony_ci int ret = 0; 139e1051a39Sopenharmony_ci BIGNUM *p1 = NULL, *gcd = NULL; 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci /* (Steps 5 a-b) prime test */ 142e1051a39Sopenharmony_ci if (BN_check_prime(p, ctx, NULL) != 1 143e1051a39Sopenharmony_ci /* (Step 5c) (√2)(2^(nbits/2 - 1) <= p <= 2^(nbits/2 - 1) */ 144e1051a39Sopenharmony_ci || ossl_rsa_check_prime_factor_range(p, nbits, ctx) != 1) 145e1051a39Sopenharmony_ci return 0; 146e1051a39Sopenharmony_ci 147e1051a39Sopenharmony_ci BN_CTX_start(ctx); 148e1051a39Sopenharmony_ci p1 = BN_CTX_get(ctx); 149e1051a39Sopenharmony_ci gcd = BN_CTX_get(ctx); 150e1051a39Sopenharmony_ci if (gcd != NULL) { 151e1051a39Sopenharmony_ci BN_set_flags(p1, BN_FLG_CONSTTIME); 152e1051a39Sopenharmony_ci BN_set_flags(gcd, BN_FLG_CONSTTIME); 153e1051a39Sopenharmony_ci ret = 1; 154e1051a39Sopenharmony_ci } else { 155e1051a39Sopenharmony_ci ret = 0; 156e1051a39Sopenharmony_ci } 157e1051a39Sopenharmony_ci ret = ret 158e1051a39Sopenharmony_ci /* (Step 5d) GCD(p-1, e) = 1 */ 159e1051a39Sopenharmony_ci && (BN_copy(p1, p) != NULL) 160e1051a39Sopenharmony_ci && BN_sub_word(p1, 1) 161e1051a39Sopenharmony_ci && BN_gcd(gcd, p1, e, ctx) 162e1051a39Sopenharmony_ci && BN_is_one(gcd); 163e1051a39Sopenharmony_ci 164e1051a39Sopenharmony_ci BN_clear(p1); 165e1051a39Sopenharmony_ci BN_CTX_end(ctx); 166e1051a39Sopenharmony_ci return ret; 167e1051a39Sopenharmony_ci} 168e1051a39Sopenharmony_ci 169e1051a39Sopenharmony_ci/* 170e1051a39Sopenharmony_ci * See SP800-56Br1 6.4.1.2.3 Part 6(a-b) Check the private exponent d 171e1051a39Sopenharmony_ci * satisfies: 172e1051a39Sopenharmony_ci * (Step 6a) 2^(nBit/2) < d < LCM(p–1, q–1). 173e1051a39Sopenharmony_ci * (Step 6b) 1 = (d*e) mod LCM(p–1, q–1) 174e1051a39Sopenharmony_ci */ 175e1051a39Sopenharmony_ciint ossl_rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx) 176e1051a39Sopenharmony_ci{ 177e1051a39Sopenharmony_ci int ret; 178e1051a39Sopenharmony_ci BIGNUM *r, *p1, *q1, *lcm, *p1q1, *gcd; 179e1051a39Sopenharmony_ci 180e1051a39Sopenharmony_ci /* (Step 6a) 2^(nbits/2) < d */ 181e1051a39Sopenharmony_ci if (BN_num_bits(rsa->d) <= (nbits >> 1)) 182e1051a39Sopenharmony_ci return 0; 183e1051a39Sopenharmony_ci 184e1051a39Sopenharmony_ci BN_CTX_start(ctx); 185e1051a39Sopenharmony_ci r = BN_CTX_get(ctx); 186e1051a39Sopenharmony_ci p1 = BN_CTX_get(ctx); 187e1051a39Sopenharmony_ci q1 = BN_CTX_get(ctx); 188e1051a39Sopenharmony_ci lcm = BN_CTX_get(ctx); 189e1051a39Sopenharmony_ci p1q1 = BN_CTX_get(ctx); 190e1051a39Sopenharmony_ci gcd = BN_CTX_get(ctx); 191e1051a39Sopenharmony_ci if (gcd != NULL) { 192e1051a39Sopenharmony_ci BN_set_flags(r, BN_FLG_CONSTTIME); 193e1051a39Sopenharmony_ci BN_set_flags(p1, BN_FLG_CONSTTIME); 194e1051a39Sopenharmony_ci BN_set_flags(q1, BN_FLG_CONSTTIME); 195e1051a39Sopenharmony_ci BN_set_flags(lcm, BN_FLG_CONSTTIME); 196e1051a39Sopenharmony_ci BN_set_flags(p1q1, BN_FLG_CONSTTIME); 197e1051a39Sopenharmony_ci BN_set_flags(gcd, BN_FLG_CONSTTIME); 198e1051a39Sopenharmony_ci ret = 1; 199e1051a39Sopenharmony_ci } else { 200e1051a39Sopenharmony_ci ret = 0; 201e1051a39Sopenharmony_ci } 202e1051a39Sopenharmony_ci ret = (ret 203e1051a39Sopenharmony_ci /* LCM(p - 1, q - 1) */ 204e1051a39Sopenharmony_ci && (ossl_rsa_get_lcm(ctx, rsa->p, rsa->q, lcm, gcd, p1, q1, 205e1051a39Sopenharmony_ci p1q1) == 1) 206e1051a39Sopenharmony_ci /* (Step 6a) d < LCM(p - 1, q - 1) */ 207e1051a39Sopenharmony_ci && (BN_cmp(rsa->d, lcm) < 0) 208e1051a39Sopenharmony_ci /* (Step 6b) 1 = (e . d) mod LCM(p - 1, q - 1) */ 209e1051a39Sopenharmony_ci && BN_mod_mul(r, rsa->e, rsa->d, lcm, ctx) 210e1051a39Sopenharmony_ci && BN_is_one(r)); 211e1051a39Sopenharmony_ci 212e1051a39Sopenharmony_ci BN_clear(r); 213e1051a39Sopenharmony_ci BN_clear(p1); 214e1051a39Sopenharmony_ci BN_clear(q1); 215e1051a39Sopenharmony_ci BN_clear(lcm); 216e1051a39Sopenharmony_ci BN_clear(gcd); 217e1051a39Sopenharmony_ci BN_CTX_end(ctx); 218e1051a39Sopenharmony_ci return ret; 219e1051a39Sopenharmony_ci} 220e1051a39Sopenharmony_ci 221e1051a39Sopenharmony_ci/* 222e1051a39Sopenharmony_ci * Check exponent is odd. 223e1051a39Sopenharmony_ci * For FIPS also check the bit length is in the range [17..256] 224e1051a39Sopenharmony_ci */ 225e1051a39Sopenharmony_ciint ossl_rsa_check_public_exponent(const BIGNUM *e) 226e1051a39Sopenharmony_ci{ 227e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 228e1051a39Sopenharmony_ci int bitlen; 229e1051a39Sopenharmony_ci 230e1051a39Sopenharmony_ci bitlen = BN_num_bits(e); 231e1051a39Sopenharmony_ci return (BN_is_odd(e) && bitlen > 16 && bitlen < 257); 232e1051a39Sopenharmony_ci#else 233e1051a39Sopenharmony_ci /* Allow small exponents larger than 1 for legacy purposes */ 234e1051a39Sopenharmony_ci return BN_is_odd(e) && BN_cmp(e, BN_value_one()) > 0; 235e1051a39Sopenharmony_ci#endif /* FIPS_MODULE */ 236e1051a39Sopenharmony_ci} 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_ci/* 239e1051a39Sopenharmony_ci * SP800-56Br1 6.4.1.2.1 (Step 5i): |p - q| > 2^(nbits/2 - 100) 240e1051a39Sopenharmony_ci * i.e- numbits(p-q-1) > (nbits/2 -100) 241e1051a39Sopenharmony_ci */ 242e1051a39Sopenharmony_ciint ossl_rsa_check_pminusq_diff(BIGNUM *diff, const BIGNUM *p, const BIGNUM *q, 243e1051a39Sopenharmony_ci int nbits) 244e1051a39Sopenharmony_ci{ 245e1051a39Sopenharmony_ci int bitlen = (nbits >> 1) - 100; 246e1051a39Sopenharmony_ci 247e1051a39Sopenharmony_ci if (!BN_sub(diff, p, q)) 248e1051a39Sopenharmony_ci return -1; 249e1051a39Sopenharmony_ci BN_set_negative(diff, 0); 250e1051a39Sopenharmony_ci 251e1051a39Sopenharmony_ci if (BN_is_zero(diff)) 252e1051a39Sopenharmony_ci return 0; 253e1051a39Sopenharmony_ci 254e1051a39Sopenharmony_ci if (!BN_sub_word(diff, 1)) 255e1051a39Sopenharmony_ci return -1; 256e1051a39Sopenharmony_ci return (BN_num_bits(diff) > bitlen); 257e1051a39Sopenharmony_ci} 258e1051a39Sopenharmony_ci 259e1051a39Sopenharmony_ci/* 260e1051a39Sopenharmony_ci * return LCM(p-1, q-1) 261e1051a39Sopenharmony_ci * 262e1051a39Sopenharmony_ci * Caller should ensure that lcm, gcd, p1, q1, p1q1 are flagged with 263e1051a39Sopenharmony_ci * BN_FLG_CONSTTIME. 264e1051a39Sopenharmony_ci */ 265e1051a39Sopenharmony_ciint ossl_rsa_get_lcm(BN_CTX *ctx, const BIGNUM *p, const BIGNUM *q, 266e1051a39Sopenharmony_ci BIGNUM *lcm, BIGNUM *gcd, BIGNUM *p1, BIGNUM *q1, 267e1051a39Sopenharmony_ci BIGNUM *p1q1) 268e1051a39Sopenharmony_ci{ 269e1051a39Sopenharmony_ci return BN_sub(p1, p, BN_value_one()) /* p-1 */ 270e1051a39Sopenharmony_ci && BN_sub(q1, q, BN_value_one()) /* q-1 */ 271e1051a39Sopenharmony_ci && BN_mul(p1q1, p1, q1, ctx) /* (p-1)(q-1) */ 272e1051a39Sopenharmony_ci && BN_gcd(gcd, p1, q1, ctx) 273e1051a39Sopenharmony_ci && BN_div(lcm, NULL, p1q1, gcd, ctx); /* LCM((p-1, q-1)) */ 274e1051a39Sopenharmony_ci} 275e1051a39Sopenharmony_ci 276e1051a39Sopenharmony_ci/* 277e1051a39Sopenharmony_ci * SP800-56Br1 6.4.2.2 Partial Public Key Validation for RSA refers to 278e1051a39Sopenharmony_ci * SP800-89 5.3.3 (Explicit) Partial Public Key Validation for RSA 279e1051a39Sopenharmony_ci * caveat is that the modulus must be as specified in SP800-56Br1 280e1051a39Sopenharmony_ci */ 281e1051a39Sopenharmony_ciint ossl_rsa_sp800_56b_check_public(const RSA *rsa) 282e1051a39Sopenharmony_ci{ 283e1051a39Sopenharmony_ci int ret = 0, status; 284e1051a39Sopenharmony_ci int nbits; 285e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 286e1051a39Sopenharmony_ci BIGNUM *gcd = NULL; 287e1051a39Sopenharmony_ci 288e1051a39Sopenharmony_ci if (rsa->n == NULL || rsa->e == NULL) 289e1051a39Sopenharmony_ci return 0; 290e1051a39Sopenharmony_ci 291e1051a39Sopenharmony_ci nbits = BN_num_bits(rsa->n); 292e1051a39Sopenharmony_ci if (nbits > OPENSSL_RSA_MAX_MODULUS_BITS) { 293e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE); 294e1051a39Sopenharmony_ci return 0; 295e1051a39Sopenharmony_ci } 296e1051a39Sopenharmony_ci 297e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 298e1051a39Sopenharmony_ci /* 299e1051a39Sopenharmony_ci * (Step a): modulus must be 2048 or 3072 (caveat from SP800-56Br1) 300e1051a39Sopenharmony_ci * NOTE: changed to allow keys >= 2048 301e1051a39Sopenharmony_ci */ 302e1051a39Sopenharmony_ci if (!ossl_rsa_sp800_56b_validate_strength(nbits, -1)) { 303e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_KEY_LENGTH); 304e1051a39Sopenharmony_ci return 0; 305e1051a39Sopenharmony_ci } 306e1051a39Sopenharmony_ci#endif 307e1051a39Sopenharmony_ci if (!BN_is_odd(rsa->n)) { 308e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS); 309e1051a39Sopenharmony_ci return 0; 310e1051a39Sopenharmony_ci } 311e1051a39Sopenharmony_ci /* (Steps b-c): 2^16 < e < 2^256, n and e must be odd */ 312e1051a39Sopenharmony_ci if (!ossl_rsa_check_public_exponent(rsa->e)) { 313e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); 314e1051a39Sopenharmony_ci return 0; 315e1051a39Sopenharmony_ci } 316e1051a39Sopenharmony_ci 317e1051a39Sopenharmony_ci ctx = BN_CTX_new_ex(rsa->libctx); 318e1051a39Sopenharmony_ci gcd = BN_new(); 319e1051a39Sopenharmony_ci if (ctx == NULL || gcd == NULL) 320e1051a39Sopenharmony_ci goto err; 321e1051a39Sopenharmony_ci 322e1051a39Sopenharmony_ci /* (Steps d-f): 323e1051a39Sopenharmony_ci * The modulus is composite, but not a power of a prime. 324e1051a39Sopenharmony_ci * The modulus has no factors smaller than 752. 325e1051a39Sopenharmony_ci */ 326e1051a39Sopenharmony_ci if (!BN_gcd(gcd, rsa->n, ossl_bn_get0_small_factors(), ctx) 327e1051a39Sopenharmony_ci || !BN_is_one(gcd)) { 328e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS); 329e1051a39Sopenharmony_ci goto err; 330e1051a39Sopenharmony_ci } 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_ci /* Highest number of MR rounds from FIPS 186-5 Section B.3 Table B.1 */ 333e1051a39Sopenharmony_ci ret = ossl_bn_miller_rabin_is_prime(rsa->n, 5, ctx, NULL, 1, &status); 334e1051a39Sopenharmony_ci#ifdef FIPS_MODULE 335e1051a39Sopenharmony_ci if (ret != 1 || status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME) { 336e1051a39Sopenharmony_ci#else 337e1051a39Sopenharmony_ci if (ret != 1 || (status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME 338e1051a39Sopenharmony_ci && (nbits >= RSA_MIN_MODULUS_BITS 339e1051a39Sopenharmony_ci || status != BN_PRIMETEST_COMPOSITE_WITH_FACTOR))) { 340e1051a39Sopenharmony_ci#endif 341e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_MODULUS); 342e1051a39Sopenharmony_ci ret = 0; 343e1051a39Sopenharmony_ci goto err; 344e1051a39Sopenharmony_ci } 345e1051a39Sopenharmony_ci 346e1051a39Sopenharmony_ci ret = 1; 347e1051a39Sopenharmony_cierr: 348e1051a39Sopenharmony_ci BN_free(gcd); 349e1051a39Sopenharmony_ci BN_CTX_free(ctx); 350e1051a39Sopenharmony_ci return ret; 351e1051a39Sopenharmony_ci} 352e1051a39Sopenharmony_ci 353e1051a39Sopenharmony_ci/* 354e1051a39Sopenharmony_ci * Perform validation of the RSA private key to check that 0 < D < N. 355e1051a39Sopenharmony_ci */ 356e1051a39Sopenharmony_ciint ossl_rsa_sp800_56b_check_private(const RSA *rsa) 357e1051a39Sopenharmony_ci{ 358e1051a39Sopenharmony_ci if (rsa->d == NULL || rsa->n == NULL) 359e1051a39Sopenharmony_ci return 0; 360e1051a39Sopenharmony_ci return BN_cmp(rsa->d, BN_value_one()) >= 0 && BN_cmp(rsa->d, rsa->n) < 0; 361e1051a39Sopenharmony_ci} 362e1051a39Sopenharmony_ci 363e1051a39Sopenharmony_ci/* 364e1051a39Sopenharmony_ci * RSA key pair validation. 365e1051a39Sopenharmony_ci * 366e1051a39Sopenharmony_ci * SP800-56Br1. 367e1051a39Sopenharmony_ci * 6.4.1.2 "RSAKPV1 Family: RSA Key - Pair Validation with a Fixed Exponent" 368e1051a39Sopenharmony_ci * 6.4.1.3 "RSAKPV2 Family: RSA Key - Pair Validation with a Random Exponent" 369e1051a39Sopenharmony_ci * 370e1051a39Sopenharmony_ci * It uses: 371e1051a39Sopenharmony_ci * 6.4.1.2.3 "rsakpv1 - crt" 372e1051a39Sopenharmony_ci * 6.4.1.3.3 "rsakpv2 - crt" 373e1051a39Sopenharmony_ci */ 374e1051a39Sopenharmony_ciint ossl_rsa_sp800_56b_check_keypair(const RSA *rsa, const BIGNUM *efixed, 375e1051a39Sopenharmony_ci int strength, int nbits) 376e1051a39Sopenharmony_ci{ 377e1051a39Sopenharmony_ci int ret = 0; 378e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 379e1051a39Sopenharmony_ci BIGNUM *r = NULL; 380e1051a39Sopenharmony_ci 381e1051a39Sopenharmony_ci if (rsa->p == NULL 382e1051a39Sopenharmony_ci || rsa->q == NULL 383e1051a39Sopenharmony_ci || rsa->e == NULL 384e1051a39Sopenharmony_ci || rsa->d == NULL 385e1051a39Sopenharmony_ci || rsa->n == NULL) { 386e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_REQUEST); 387e1051a39Sopenharmony_ci return 0; 388e1051a39Sopenharmony_ci } 389e1051a39Sopenharmony_ci /* (Step 1): Check Ranges */ 390e1051a39Sopenharmony_ci if (!ossl_rsa_sp800_56b_validate_strength(nbits, strength)) 391e1051a39Sopenharmony_ci return 0; 392e1051a39Sopenharmony_ci 393e1051a39Sopenharmony_ci /* If the exponent is known */ 394e1051a39Sopenharmony_ci if (efixed != NULL) { 395e1051a39Sopenharmony_ci /* (2): Check fixed exponent matches public exponent. */ 396e1051a39Sopenharmony_ci if (BN_cmp(efixed, rsa->e) != 0) { 397e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_REQUEST); 398e1051a39Sopenharmony_ci return 0; 399e1051a39Sopenharmony_ci } 400e1051a39Sopenharmony_ci } 401e1051a39Sopenharmony_ci /* (Step 1.c): e is odd integer 65537 <= e < 2^256 */ 402e1051a39Sopenharmony_ci if (!ossl_rsa_check_public_exponent(rsa->e)) { 403e1051a39Sopenharmony_ci /* exponent out of range */ 404e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); 405e1051a39Sopenharmony_ci return 0; 406e1051a39Sopenharmony_ci } 407e1051a39Sopenharmony_ci /* (Step 3.b): check the modulus */ 408e1051a39Sopenharmony_ci if (nbits != BN_num_bits(rsa->n)) { 409e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_KEYPAIR); 410e1051a39Sopenharmony_ci return 0; 411e1051a39Sopenharmony_ci } 412e1051a39Sopenharmony_ci 413e1051a39Sopenharmony_ci ctx = BN_CTX_new_ex(rsa->libctx); 414e1051a39Sopenharmony_ci if (ctx == NULL) 415e1051a39Sopenharmony_ci return 0; 416e1051a39Sopenharmony_ci 417e1051a39Sopenharmony_ci BN_CTX_start(ctx); 418e1051a39Sopenharmony_ci r = BN_CTX_get(ctx); 419e1051a39Sopenharmony_ci if (r == NULL || !BN_mul(r, rsa->p, rsa->q, ctx)) 420e1051a39Sopenharmony_ci goto err; 421e1051a39Sopenharmony_ci /* (Step 4.c): Check n = pq */ 422e1051a39Sopenharmony_ci if (BN_cmp(rsa->n, r) != 0) { 423e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_REQUEST); 424e1051a39Sopenharmony_ci goto err; 425e1051a39Sopenharmony_ci } 426e1051a39Sopenharmony_ci 427e1051a39Sopenharmony_ci /* (Step 5): check prime factors p & q */ 428e1051a39Sopenharmony_ci ret = ossl_rsa_check_prime_factor(rsa->p, rsa->e, nbits, ctx) 429e1051a39Sopenharmony_ci && ossl_rsa_check_prime_factor(rsa->q, rsa->e, nbits, ctx) 430e1051a39Sopenharmony_ci && (ossl_rsa_check_pminusq_diff(r, rsa->p, rsa->q, nbits) > 0) 431e1051a39Sopenharmony_ci /* (Step 6): Check the private exponent d */ 432e1051a39Sopenharmony_ci && ossl_rsa_check_private_exponent(rsa, nbits, ctx) 433e1051a39Sopenharmony_ci /* 6.4.1.2.3 (Step 7): Check the CRT components */ 434e1051a39Sopenharmony_ci && ossl_rsa_check_crt_components(rsa, ctx); 435e1051a39Sopenharmony_ci if (ret != 1) 436e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_KEYPAIR); 437e1051a39Sopenharmony_ci 438e1051a39Sopenharmony_cierr: 439e1051a39Sopenharmony_ci BN_clear(r); 440e1051a39Sopenharmony_ci BN_CTX_end(ctx); 441e1051a39Sopenharmony_ci BN_CTX_free(ctx); 442e1051a39Sopenharmony_ci return ret; 443e1051a39Sopenharmony_ci} 444