aboutsummaryrefslogtreecommitdiff
path: root/crypto/rsa/rsa_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/rsa/rsa_lib.c')
-rw-r--r--crypto/rsa/rsa_lib.c119
1 files changed, 99 insertions, 20 deletions
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index c9c661b1ede9..d9ceb8088005 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2024 The OpenSSL Project Authors. 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
@@ -76,15 +76,18 @@ static RSA *rsa_new_intern(ENGINE *engine, OSSL_LIB_CTX *libctx)
{
RSA *ret = OPENSSL_zalloc(sizeof(*ret));
- if (ret == NULL) {
- ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
+ if (ret == NULL)
return NULL;
- }
- ret->references = 1;
ret->lock = CRYPTO_THREAD_lock_new();
if (ret->lock == NULL) {
- ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
+ ERR_raise(ERR_LIB_RSA, ERR_R_CRYPTO_LIB);
+ OPENSSL_free(ret);
+ return NULL;
+ }
+
+ if (!CRYPTO_NEW_REF(&ret->references, 1)) {
+ CRYPTO_THREAD_lock_free(ret->lock);
OPENSSL_free(ret);
return NULL;
}
@@ -137,8 +140,8 @@ void RSA_free(RSA *r)
if (r == NULL)
return;
- CRYPTO_DOWN_REF(&r->references, &i, r->lock);
- REF_PRINT_COUNT("RSA", r);
+ CRYPTO_DOWN_REF(&r->references, &i);
+ REF_PRINT_COUNT("RSA", i, r);
if (i > 0)
return;
REF_ASSERT_ISNT(i < 0);
@@ -154,9 +157,15 @@ void RSA_free(RSA *r)
#endif
CRYPTO_THREAD_lock_free(r->lock);
+ CRYPTO_FREE_REF(&r->references);
+#ifdef OPENSSL_PEDANTIC_ZEROIZATION
+ BN_clear_free(r->n);
+ BN_clear_free(r->e);
+#else
BN_free(r->n);
BN_free(r->e);
+#endif
BN_clear_free(r->d);
BN_clear_free(r->p);
BN_clear_free(r->q);
@@ -181,10 +190,10 @@ int RSA_up_ref(RSA *r)
{
int i;
- if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
+ if (CRYPTO_UP_REF(&r->references, &i) <= 0)
return 0;
- REF_PRINT_COUNT("RSA", r);
+ REF_PRINT_COUNT("RSA", i, r);
REF_ASSERT_ISNT(i < 2);
return i > 1 ? 1 : 0;
}
@@ -740,9 +749,13 @@ int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2)
DEFINE_STACK_OF(BIGNUM)
-int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
- const STACK_OF(BIGNUM) *exps,
- const STACK_OF(BIGNUM) *coeffs)
+/*
+ * Note: This function deletes values from the parameter
+ * stack values as they are consumed and set in the RSA key.
+ */
+int ossl_rsa_set0_all_params(RSA *r, STACK_OF(BIGNUM) *primes,
+ STACK_OF(BIGNUM) *exps,
+ STACK_OF(BIGNUM) *coeffs)
{
#ifndef FIPS_MODULE
STACK_OF(RSA_PRIME_INFO) *prime_infos, *old_infos = NULL;
@@ -753,6 +766,8 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
return 0;
pnum = sk_BIGNUM_num(primes);
+
+ /* we need at least 2 primes */
if (pnum < 2)
return 0;
@@ -760,6 +775,17 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
sk_BIGNUM_value(primes, 1)))
return 0;
+ /*
+ * if we managed to set everything above, remove those elements from the
+ * stack
+ * Note, we do this after the above all to ensure that we have taken
+ * ownership of all the elements in the RSA key to avoid memory leaks
+ * we also use delete 0 here as we are grabbing items from the end of the
+ * stack rather than the start, otherwise we could use pop
+ */
+ sk_BIGNUM_delete(primes, 0);
+ sk_BIGNUM_delete(primes, 0);
+
if (pnum == sk_BIGNUM_num(exps)
&& pnum == sk_BIGNUM_num(coeffs) + 1) {
@@ -767,6 +793,11 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
sk_BIGNUM_value(exps, 1),
sk_BIGNUM_value(coeffs, 0)))
return 0;
+
+ /* as above, once we consume the above params, delete them from the list */
+ sk_BIGNUM_delete(exps, 0);
+ sk_BIGNUM_delete(exps, 0);
+ sk_BIGNUM_delete(coeffs, 0);
}
#ifndef FIPS_MODULE
@@ -782,19 +813,17 @@ int ossl_rsa_set0_all_params(RSA *r, const STACK_OF(BIGNUM) *primes,
return 0;
for (i = 2; i < pnum; i++) {
- BIGNUM *prime = sk_BIGNUM_value(primes, i);
- BIGNUM *exp = sk_BIGNUM_value(exps, i);
- BIGNUM *coeff = sk_BIGNUM_value(coeffs, i - 1);
+ BIGNUM *prime = sk_BIGNUM_pop(primes);
+ BIGNUM *exp = sk_BIGNUM_pop(exps);
+ BIGNUM *coeff = sk_BIGNUM_pop(coeffs);
RSA_PRIME_INFO *pinfo = NULL;
if (!ossl_assert(prime != NULL && exp != NULL && coeff != NULL))
goto err;
/* Using ossl_rsa_multip_info_new() is wasteful, so allocate directly */
- if ((pinfo = OPENSSL_zalloc(sizeof(*pinfo))) == NULL) {
- ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
+ if ((pinfo = OPENSSL_zalloc(sizeof(*pinfo))) == NULL)
goto err;
- }
pinfo->r = prime;
pinfo->d = exp;
@@ -877,6 +906,56 @@ int ossl_rsa_get0_all_params(RSA *r, STACK_OF(BIGNUM_const) *primes,
return 1;
}
+#define safe_BN_num_bits(_k_) (((_k_) == NULL) ? 0 : BN_num_bits((_k_)))
+int ossl_rsa_check_factors(RSA *r)
+{
+ int valid = 0;
+ int n, i, bits;
+ STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null();
+ STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null();
+ STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null();
+
+ if (factors == NULL || exps == NULL || coeffs == NULL)
+ goto done;
+
+ /*
+ * Simple sanity check for RSA key. All RSA key parameters
+ * must be less-than/equal-to RSA parameter n.
+ */
+ ossl_rsa_get0_all_params(r, factors, exps, coeffs);
+ n = safe_BN_num_bits(RSA_get0_n(r));
+
+ if (safe_BN_num_bits(RSA_get0_d(r)) > n)
+ goto done;
+
+ for (i = 0; i < sk_BIGNUM_const_num(exps); i++) {
+ bits = safe_BN_num_bits(sk_BIGNUM_const_value(exps, i));
+ if (bits > n)
+ goto done;
+ }
+
+ for (i = 0; i < sk_BIGNUM_const_num(factors); i++) {
+ bits = safe_BN_num_bits(sk_BIGNUM_const_value(factors, i));
+ if (bits > n)
+ goto done;
+ }
+
+ for (i = 0; i < sk_BIGNUM_const_num(coeffs); i++) {
+ bits = safe_BN_num_bits(sk_BIGNUM_const_value(coeffs, i));
+ if (bits > n)
+ goto done;
+ }
+
+ valid = 1;
+
+done:
+ sk_BIGNUM_const_free(factors);
+ sk_BIGNUM_const_free(exps);
+ sk_BIGNUM_const_free(coeffs);
+
+ return valid;
+}
+
#ifndef FIPS_MODULE
/* Helpers to set or get diverse hash algorithm names */
static int int_set_rsa_md_name(EVP_PKEY_CTX *ctx,
@@ -1127,7 +1206,7 @@ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen)
if (ret <= 0)
return ret;
- /* Ownership is supposed to be transfered to the callee. */
+ /* Ownership is supposed to be transferred to the callee. */
OPENSSL_free(label);
return 1;
}