- {
- return(CRYPTO_get_ex_data(&r->ex_data,idx));
- }
-
-int RSA_size(const RSA *r)
- {
- return(BN_num_bytes(r->n));
- }
-
-int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding)
- {
- return(ENGINE_get_RSA(rsa->engine)->rsa_pub_enc(flen,
- from, to, rsa, padding));
- }
-
-int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding)
- {
- return(ENGINE_get_RSA(rsa->engine)->rsa_priv_enc(flen,
- from, to, rsa, padding));
- }
-
-int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding)
- {
- return(ENGINE_get_RSA(rsa->engine)->rsa_priv_dec(flen,
- from, to, rsa, padding));
- }
-
-int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
- RSA *rsa, int padding)
- {
- return(ENGINE_get_RSA(rsa->engine)->rsa_pub_dec(flen,
- from, to, rsa, padding));
- }
-
-int RSA_flags(const RSA *r)
- {
- return((r == NULL)?0:ENGINE_get_RSA(r->engine)->flags);
- }
-
-void RSA_blinding_off(RSA *rsa)
- {
- if (rsa->blinding != NULL)
- {
- BN_BLINDING_free(rsa->blinding);
- rsa->blinding=NULL;
- }
- rsa->flags&= ~RSA_FLAG_BLINDING;
- }
-
-int RSA_blinding_on(RSA *rsa, BN_CTX *p_ctx)
- {
- BIGNUM *A,*Ai;
- BN_CTX *ctx;
- int ret=0;
-
- if (p_ctx == NULL)
- {
- if ((ctx=BN_CTX_new()) == NULL) goto err;
- }
- else
- ctx=p_ctx;
-
- if (rsa->blinding != NULL)
- BN_BLINDING_free(rsa->blinding);
-
- BN_CTX_start(ctx);
- A = BN_CTX_get(ctx);
- if (!BN_rand_range(A,rsa->n)) goto err;
- if ((Ai=BN_mod_inverse(NULL,A,rsa->n,ctx)) == NULL) goto err;
-
- if (!ENGINE_get_RSA(rsa->engine)->bn_mod_exp(A,A,
- rsa->e,rsa->n,ctx,rsa->_method_mod_n))
- goto err;
- rsa->blinding=BN_BLINDING_new(A,Ai,rsa->n);
- rsa->flags|=RSA_FLAG_BLINDING;
- BN_free(Ai);
- ret=1;
-err:
- BN_CTX_end(ctx);
- if (ctx != p_ctx) BN_CTX_free(ctx);
- return(ret);
- }
-
-int RSA_memory_lock(RSA *r)
- {
- 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=sizeof(BIGNUM)*6;
- off=k/sizeof(BN_ULONG)+1;
- j=1;
- for (i=0; i<6; i++)
- j+= (*t[i])->top;
- if ((p=OPENSSL_malloc_locked((off+j)*sizeof(BN_ULONG))) == NULL)
- {
- RSAerr(RSA_F_MEMORY_LOCK,ERR_R_MALLOC_FAILURE);
- return(0);
- }
- bn=(BIGNUM *)p;
- ul=(BN_ULONG *)&(p[off]);
- for (i=0; i<6; i++)
- {
- b= *(t[i]);
- *(t[i])= &(bn[i]);
- memcpy((char *)&(bn[i]),(char *)b,sizeof(BIGNUM));
- bn[i].flags=BN_FLG_STATIC_DATA;
- bn[i].d=ul;
- memcpy((char *)ul,b->d,sizeof(BN_ULONG)*b->top);
- ul+=b->top;
- BN_clear_free(b);
- }
-
- /* I should fix this so it can still be done */
- r->flags&= ~(RSA_FLAG_CACHE_PRIVATE|RSA_FLAG_CACHE_PUBLIC);
-
- r->bignum_data=p;
- return(1);
- }
+{
+ return CRYPTO_get_ex_data(&r->ex_data, idx);
+}
+
+/*
+ * Define a scaling constant for our fixed point arithmetic.
+ * This value must be a power of two because the base two logarithm code
+ * makes this assumption. The exponent must also be a multiple of three so
+ * that the scale factor has an exact cube root. Finally, the scale factor
+ * should not be so large that a multiplication of two scaled numbers
+ * overflows a 64 bit unsigned integer.
+ */
+static const unsigned int scale = 1 << 18;
+static const unsigned int cbrt_scale = 1 << (2 * 18 / 3);
+
+/* Define some constants, none exceed 32 bits */
+static const unsigned int log_2 = 0x02c5c8; /* scale * log(2) */
+static const unsigned int log_e = 0x05c551; /* scale * log2(M_E) */
+static const unsigned int c1_923 = 0x07b126; /* scale * 1.923 */
+static const unsigned int c4_690 = 0x12c28f; /* scale * 4.690 */
+
+/*
+ * Multiply two scaled integers together and rescale the result.
+ */
+static ossl_inline uint64_t mul2(uint64_t a, uint64_t b)
+{
+ return a * b / scale;
+}
+
+/*
+ * Calculate the cube root of a 64 bit scaled integer.
+ * Although the cube root of a 64 bit number does fit into a 32 bit unsigned
+ * integer, this is not guaranteed after scaling, so this function has a
+ * 64 bit return. This uses the shifting nth root algorithm with some
+ * algebraic simplifications.
+ */
+static uint64_t icbrt64(uint64_t x)
+{
+ uint64_t r = 0;
+ uint64_t b;
+ int s;
+
+ for (s = 63; s >= 0; s -= 3) {
+ r <<= 1;
+ b = 3 * r * (r + 1) + 1;
+ if ((x >> s) >= b) {
+ x -= b << s;
+ r++;
+ }
+ }
+ return r * cbrt_scale;
+}
+
+/*
+ * Calculate the natural logarithm of a 64 bit scaled integer.
+ * This is done by calculating a base two logarithm and scaling.
+ * The maximum logarithm (base 2) is 64 and this reduces base e, so
+ * a 32 bit result should not overflow. The argument passed must be
+ * greater than unity so we don't need to handle negative results.
+ */
+static uint32_t ilog_e(uint64_t v)
+{
+ uint32_t i, r = 0;
+
+ /*
+ * Scale down the value into the range 1 .. 2.
+ *
+ * If fractional numbers need to be processed, another loop needs
+ * to go here that checks v < scale and if so multiplies it by 2 and
+ * reduces r by scale. This also means making r signed.
+ */
+ while (v >= 2 * scale) {
+ v >>= 1;
+ r += scale;
+ }
+ for (i = scale / 2; i != 0; i /= 2) {
+ v = mul2(v, v);
+ if (v >= 2 * scale) {
+ v >>= 1;
+ r += i;
+ }
+ }
+ r = (r * (uint64_t)scale) / log_e;
+ return r;
+}
+
+/*
+ * NIST SP 800-56B rev 2 Appendix D: Maximum Security Strength Estimates for IFC
+ * Modulus Lengths.
+ *
+ * E = \frac{1.923 \sqrt[3]{nBits \cdot log_e(2)}
+ * \cdot(log_e(nBits \cdot log_e(2))^{2/3} - 4.69}{log_e(2)}
+ * The two cube roots are merged together here.
+ */
+static uint16_t rsa_compute_security_bits(int n)
+{
+ uint64_t x;
+ uint32_t lx;
+ uint16_t y;
+
+ /* Look for common values as listed in SP 800-56B rev 2 Appendix D */
+ switch (n) {
+ case 2048:
+ return 112;
+ case 3072:
+ return 128;
+ case 4096:
+ return 152;
+ case 6144:
+ return 176;
+ case 8192:
+ return 200;
+ }
+ /*
+ * The first incorrect result (i.e. not accurate or off by one low) occurs
+ * for n = 699668. The true value here is 1200. Instead of using this n
+ * as the check threshold, the smallest n such that the correct result is
+ * 1200 is used instead.
+ */
+ if (n >= 687737)
+ return 1200;
+ if (n < 8)
+ return 0;
+
+ x = n * (uint64_t)log_2;
+ lx = ilog_e(x);
+ y = (uint16_t)((mul2(c1_923, icbrt64(mul2(mul2(x, lx), lx))) - c4_690)
+ / log_2);
+ return (y + 4) & ~7;
+}
+
+int RSA_security_bits(const RSA *rsa)
+{
+ 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 rsa_compute_security_bits(bits);
+}
+
+int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
+{
+ /* If the fields n and e in r are NULL, the corresponding input
+ * parameters MUST be non-NULL for n and e. d may be
+ * left NULL (in case only the public key is used).
+ */
+ if ((r->n == NULL && n == NULL)
+ || (r->e == NULL && e == NULL))
+ return 0;
+
+ if (n != NULL) {
+ BN_free(r->n);
+ r->n = n;
+ }
+ if (e != NULL) {
+ BN_free(r->e);
+ r->e = e;
+ }
+ if (d != NULL) {
+ BN_clear_free(r->d);
+ r->d = d;
+ }
+
+ return 1;
+}
+
+int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q)
+{
+ /* If the fields p and q in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((r->p == NULL && p == NULL)
+ || (r->q == NULL && q == NULL))
+ return 0;
+
+ if (p != NULL) {
+ BN_clear_free(r->p);
+ r->p = p;
+ }
+ if (q != NULL) {
+ BN_clear_free(r->q);
+ r->q = q;
+ }
+
+ return 1;
+}
+
+int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp)
+{
+ /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
+ * parameters MUST be non-NULL.
+ */
+ if ((r->dmp1 == NULL && dmp1 == NULL)
+ || (r->dmq1 == NULL && dmq1 == NULL)
+ || (r->iqmp == NULL && iqmp == NULL))
+ return 0;
+
+ if (dmp1 != NULL) {
+ BN_clear_free(r->dmp1);
+ r->dmp1 = dmp1;
+ }
+ if (dmq1 != NULL) {
+ BN_clear_free(r->dmq1);
+ r->dmq1 = dmq1;
+ }
+ if (iqmp != NULL) {
+ BN_clear_free(r->iqmp);
+ r->iqmp = iqmp;
+ }
+
+ return 1;
+}