Always call the new_session_cb when issuing a NewSessionTicket in TLSv1.3
[openssl.git] / crypto / rsa / rsa_lib.c
index 9ba86d856ac83fcd215d552e68264d6b32cbef13..133ba2185c5b8713d4dcce7e1288029bedfc3c67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
 #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"
 
-static const RSA_METHOD *default_RSA_meth = NULL;
-
 RSA *RSA_new(void)
 {
-    RSA *r = RSA_new_method(NULL);
-
-    return r;
-}
-
-void RSA_set_default_method(const RSA_METHOD *meth)
-{
-    default_RSA_meth = meth;
-}
-
-const RSA_METHOD *RSA_get_default_method(void)
-{
-    if (default_RSA_meth == NULL) {
-#ifdef RSA_NULL
-        default_RSA_meth = RSA_null_method();
-#else
-        default_RSA_meth = RSA_PKCS1_OpenSSL();
-#endif
-    }
-
-    return default_RSA_meth;
+    return RSA_new_method(NULL);
 }
 
 const RSA_METHOD *RSA_get_method(const RSA *rsa)
@@ -93,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) {
@@ -128,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;
@@ -152,6 +133,8 @@ void RSA_free(RSA *r)
     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);
@@ -162,71 +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_memory_lock(RSA *r)
+int RSA_security_bits(const RSA *rsa)
 {
-    int i, j, k, off;
-    char *p;
-    BIGNUM *bn, **t[6], *b;
-    BN_ULONG *ul;
-
-    if (r->d == NULL)
-        return (1);
-    t[0] = &r->d;
-    t[1] = &r->p;
-    t[2] = &r->q;
-    t[3] = &r->dmp1;
-    t[4] = &r->dmq1;
-    t[5] = &r->iqmp;
-    k = bn_sizeof_BIGNUM() * 6;
-    off = k / sizeof(BN_ULONG) + 1;
-    j = 1;
-    for (i = 0; i < 6; i++)
-        j += bn_get_top(*t[i]);
-    if ((p = OPENSSL_malloc((off + j) * sizeof(*p))) == NULL) {
-        RSAerr(RSA_F_RSA_MEMORY_LOCK, ERR_R_MALLOC_FAILURE);
-        return (0);
-    }
-    memset(p, 0, sizeof(*p) * (off + j));
-    bn = (BIGNUM *)p;
-    ul = (BN_ULONG *)&(p[off]);
-    for (i = 0; i < 6; i++) {
-        b = *(t[i]);
-        *(t[i]) = bn_array_el(bn, i);
-        memcpy(bn_array_el(bn, i), b, bn_sizeof_BIGNUM());
-        memcpy(ul, bn_get_words(b), sizeof(*ul) * bn_get_top(b));
-        bn_set_static_words(bn_array_el(bn, i), ul, bn_get_top(b));
-        ul += bn_get_top(b);
-        BN_clear_free(b);
-    }
+    int bits = BN_num_bits(rsa->n);
 
-    /* I should fix this so it can still be done */
-    r->flags &= ~(RSA_FLAG_CACHE_PRIVATE | RSA_FLAG_CACHE_PUBLIC);
+    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);
 
-    r->bignum_data = p;
-    return (1);
-}
-
-int RSA_security_bits(const RSA *rsa)
-{
-    return BN_security_bits(BN_num_bits(rsa->n), -1);
+        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)
@@ -302,6 +250,71 @@ int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *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)
 {
@@ -321,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)
@@ -333,6 +376,32 @@ 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;
+}
+
 void RSA_clear_flags(RSA *r, int flags)
 {
     r->flags &= ~flags;
@@ -348,7 +417,23 @@ void RSA_set_flags(RSA *r, int flags)
     r->flags |= flags;
 }
 
-ENGINE *RSA_get0_engine(RSA *r)
+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);
+}