summaryrefslogtreecommitdiff
path: root/deps/openssl/openssl/crypto/rsa/rsa_lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/openssl/openssl/crypto/rsa/rsa_lib.c')
-rw-r--r--deps/openssl/openssl/crypto/rsa/rsa_lib.c223
1 files changed, 207 insertions, 16 deletions
diff --git a/deps/openssl/openssl/crypto/rsa/rsa_lib.c b/deps/openssl/openssl/crypto/rsa/rsa_lib.c
index d99d04916d..49c34b7c36 100644
--- a/deps/openssl/openssl/crypto/rsa/rsa_lib.c
+++ b/deps/openssl/openssl/crypto/rsa/rsa_lib.c
@@ -10,9 +10,11 @@
#include <stdio.h>
#include <openssl/crypto.h>
#include "internal/cryptlib.h"
-#include <openssl/lhash.h>
+#include "internal/refcount.h"
#include "internal/bn_int.h"
#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include "internal/evp_int.h"
#include "rsa_locl.h"
RSA *RSA_new(void)
@@ -71,8 +73,9 @@ RSA *RSA_new_method(ENGINE *engine)
goto err;
}
ret->engine = engine;
- } else
+ } else {
ret->engine = ENGINE_get_default_RSA();
+ }
if (ret->engine) {
ret->meth = ENGINE_get_RSA(ret->engine);
if (ret->meth == NULL) {
@@ -106,7 +109,7 @@ void RSA_free(RSA *r)
if (r == NULL)
return;
- CRYPTO_atomic_add(&r->references, -1, &i, r->lock);
+ CRYPTO_DOWN_REF(&r->references, &i, r->lock);
REF_PRINT_COUNT("RSA", r);
if (i > 0)
return;
@@ -122,14 +125,16 @@ void RSA_free(RSA *r)
CRYPTO_THREAD_lock_free(r->lock);
- BN_clear_free(r->n);
- BN_clear_free(r->e);
+ BN_free(r->n);
+ BN_free(r->e);
BN_clear_free(r->d);
BN_clear_free(r->p);
BN_clear_free(r->q);
BN_clear_free(r->dmp1);
BN_clear_free(r->dmq1);
BN_clear_free(r->iqmp);
+ RSA_PSS_PARAMS_free(r->pss);
+ sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free);
BN_BLINDING_free(r->blinding);
BN_BLINDING_free(r->mt_blinding);
OPENSSL_free(r->bignum_data);
@@ -140,27 +145,36 @@ int RSA_up_ref(RSA *r)
{
int i;
- if (CRYPTO_atomic_add(&r->references, 1, &i, r->lock) <= 0)
+ if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0)
return 0;
REF_PRINT_COUNT("RSA", r);
REF_ASSERT_ISNT(i < 2);
- return ((i > 1) ? 1 : 0);
+ return i > 1 ? 1 : 0;
}
int RSA_set_ex_data(RSA *r, int idx, void *arg)
{
- return (CRYPTO_set_ex_data(&r->ex_data, idx, arg));
+ return CRYPTO_set_ex_data(&r->ex_data, idx, arg);
}
void *RSA_get_ex_data(const RSA *r, int idx)
{
- return (CRYPTO_get_ex_data(&r->ex_data, idx));
+ return CRYPTO_get_ex_data(&r->ex_data, idx);
}
int RSA_security_bits(const RSA *rsa)
{
- return BN_security_bits(BN_num_bits(rsa->n), -1);
+ int bits = BN_num_bits(rsa->n);
+
+ if (rsa->version == RSA_ASN1_VERSION_MULTI) {
+ /* This ought to mean that we have private key at hand. */
+ int ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos);
+
+ if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits))
+ return 0;
+ }
+ return BN_security_bits(bits, -1);
}
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
@@ -182,7 +196,7 @@ int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
r->e = e;
}
if (d != NULL) {
- BN_free(r->d);
+ BN_clear_free(r->d);
r->d = d;
}
@@ -199,11 +213,11 @@ int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
return 0;
if (p != NULL) {
- BN_free(r->p);
+ BN_clear_free(r->p);
r->p = p;
}
if (q != NULL) {
- BN_free(r->q);
+ BN_clear_free(r->q);
r->q = q;
}
@@ -221,21 +235,86 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
return 0;
if (dmp1 != NULL) {
- BN_free(r->dmp1);
+ BN_clear_free(r->dmp1);
r->dmp1 = dmp1;
}
if (dmq1 != NULL) {
- BN_free(r->dmq1);
+ BN_clear_free(r->dmq1);
r->dmq1 = dmq1;
}
if (iqmp != NULL) {
- BN_free(r->iqmp);
+ BN_clear_free(r->iqmp);
r->iqmp = iqmp;
}
return 1;
}
+/*
+ * Is it better to export RSA_PRIME_INFO structure
+ * and related functions to let user pass a triplet?
+ */
+int RSA_set0_multi_prime_params(RSA *r, BIGNUM *primes[], BIGNUM *exps[],
+ BIGNUM *coeffs[], int pnum)
+{
+ STACK_OF(RSA_PRIME_INFO) *prime_infos, *old = NULL;
+ RSA_PRIME_INFO *pinfo;
+ int i;
+
+ if (primes == NULL || exps == NULL || coeffs == NULL || pnum == 0)
+ return 0;
+
+ prime_infos = sk_RSA_PRIME_INFO_new_reserve(NULL, pnum);
+ if (prime_infos == NULL)
+ return 0;
+
+ if (r->prime_infos != NULL)
+ old = r->prime_infos;
+
+ for (i = 0; i < pnum; i++) {
+ pinfo = rsa_multip_info_new();
+ if (pinfo == NULL)
+ goto err;
+ if (primes[i] != NULL && exps[i] != NULL && coeffs[i] != NULL) {
+ BN_free(pinfo->r);
+ BN_free(pinfo->d);
+ BN_free(pinfo->t);
+ pinfo->r = primes[i];
+ pinfo->d = exps[i];
+ pinfo->t = coeffs[i];
+ } else {
+ rsa_multip_info_free(pinfo);
+ goto err;
+ }
+ (void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo);
+ }
+
+ r->prime_infos = prime_infos;
+
+ if (!rsa_multip_calc_product(r)) {
+ r->prime_infos = old;
+ goto err;
+ }
+
+ if (old != NULL) {
+ /*
+ * This is hard to deal with, since the old infos could
+ * also be set by this function and r, d, t should not
+ * be freed in that case. So currently, stay consistent
+ * with other *set0* functions: just free it...
+ */
+ sk_RSA_PRIME_INFO_pop_free(old, rsa_multip_info_free);
+ }
+
+ r->version = RSA_ASN1_VERSION_MULTI;
+
+ return 1;
+ err:
+ /* r, d, t should not be freed */
+ sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex);
+ return 0;
+}
+
void RSA_get0_key(const RSA *r,
const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
{
@@ -255,6 +334,36 @@ void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q)
*q = r->q;
}
+int RSA_get_multi_prime_extra_count(const RSA *r)
+{
+ int pnum;
+
+ pnum = sk_RSA_PRIME_INFO_num(r->prime_infos);
+ if (pnum <= 0)
+ pnum = 0;
+ return pnum;
+}
+
+int RSA_get0_multi_prime_factors(const RSA *r, const BIGNUM *primes[])
+{
+ int pnum, i;
+ RSA_PRIME_INFO *pinfo;
+
+ if ((pnum = RSA_get_multi_prime_extra_count(r)) == 0)
+ return 0;
+
+ /*
+ * return other primes
+ * it's caller's responsibility to allocate oth_primes[pnum]
+ */
+ for (i = 0; i < pnum; i++) {
+ pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i);
+ primes[i] = pinfo->r;
+ }
+
+ return 1;
+}
+
void RSA_get0_crt_params(const RSA *r,
const BIGNUM **dmp1, const BIGNUM **dmq1,
const BIGNUM **iqmp)
@@ -267,6 +376,72 @@ void RSA_get0_crt_params(const RSA *r,
*iqmp = r->iqmp;
}
+int RSA_get0_multi_prime_crt_params(const RSA *r, const BIGNUM *exps[],
+ const BIGNUM *coeffs[])
+{
+ int pnum;
+
+ if ((pnum = RSA_get_multi_prime_extra_count(r)) == 0)
+ return 0;
+
+ /* return other primes */
+ if (exps != NULL || coeffs != NULL) {
+ RSA_PRIME_INFO *pinfo;
+ int i;
+
+ /* it's the user's job to guarantee the buffer length */
+ for (i = 0; i < pnum; i++) {
+ pinfo = sk_RSA_PRIME_INFO_value(r->prime_infos, i);
+ if (exps != NULL)
+ exps[i] = pinfo->d;
+ if (coeffs != NULL)
+ coeffs[i] = pinfo->t;
+ }
+ }
+
+ return 1;
+}
+
+const BIGNUM *RSA_get0_n(const RSA *r)
+{
+ return r->n;
+}
+
+const BIGNUM *RSA_get0_e(const RSA *r)
+{
+ return r->e;
+}
+
+const BIGNUM *RSA_get0_d(const RSA *r)
+{
+ return r->d;
+}
+
+const BIGNUM *RSA_get0_p(const RSA *r)
+{
+ return r->p;
+}
+
+const BIGNUM *RSA_get0_q(const RSA *r)
+{
+ return r->q;
+}
+
+const BIGNUM *RSA_get0_dmp1(const RSA *r)
+{
+ return r->dmp1;
+}
+
+const BIGNUM *RSA_get0_dmq1(const RSA *r)
+{
+ return r->dmq1;
+}
+
+const BIGNUM *RSA_get0_iqmp(const RSA *r)
+{
+ return r->iqmp;
+}
+
void RSA_clear_flags(RSA *r, int flags)
{
r->flags &= ~flags;
@@ -282,7 +457,23 @@ void RSA_set_flags(RSA *r, int flags)
r->flags |= flags;
}
+int RSA_get_version(RSA *r)
+{
+ /* { two-prime(0), multi(1) } */
+ return r->version;
+}
+
ENGINE *RSA_get0_engine(const RSA *r)
{
return r->engine;
}
+
+int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2)
+{
+ /* If key type not RSA or RSA-PSS return error */
+ if (ctx != NULL && ctx->pmeth != NULL
+ && ctx->pmeth->pkey_id != EVP_PKEY_RSA
+ && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
+ return -1;
+ return EVP_PKEY_CTX_ctrl(ctx, -1, optype, cmd, p1, p2);
+}