1169609Sscottl/* crypto/rsa/rsa_lib.c */
2169609Sscottl/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3169609Sscottl * All rights reserved.
4169609Sscottl *
5169609Sscottl * This package is an SSL implementation written
6169609Sscottl * by Eric Young (eay@cryptsoft.com).
7169609Sscottl * The implementation was written so as to conform with Netscapes SSL.
8169609Sscottl *
9169609Sscottl * This library is free for commercial and non-commercial use as long as
10169609Sscottl * the following conditions are aheared to.  The following conditions
11169609Sscottl * apply to all code found in this distribution, be it the RC4, RSA,
12169609Sscottl * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13169609Sscottl * included with this distribution is covered by the same copyright terms
14169609Sscottl * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15169609Sscottl *
16169609Sscottl * Copyright remains Eric Young's, and as such any Copyright notices in
17169609Sscottl * the code are not to be removed.
18169609Sscottl * If this package is used in a product, Eric Young should be given attribution
19169609Sscottl * as the author of the parts of the library used.
20169609Sscottl * This can be in the form of a textual message at program startup or
21169609Sscottl * in documentation (online or textual) provided with the package.
22169609Sscottl *
23169609Sscottl * Redistribution and use in source and binary forms, with or without
24169609Sscottl * modification, are permitted provided that the following conditions
25169609Sscottl * are met:
26169609Sscottl * 1. Redistributions of source code must retain the copyright
27169609Sscottl *    notice, this list of conditions and the following disclaimer.
28169609Sscottl * 2. Redistributions in binary form must reproduce the above copyright
29169609Sscottl *    notice, this list of conditions and the following disclaimer in the
30169609Sscottl *    documentation and/or other materials provided with the distribution.
31169609Sscottl * 3. All advertising materials mentioning features or use of this software
32169609Sscottl *    must display the following acknowledgement:
33169609Sscottl *    "This product includes cryptographic software written by
34169609Sscottl *     Eric Young (eay@cryptsoft.com)"
35169609Sscottl *    The word 'cryptographic' can be left out if the rouines from the library
36169609Sscottl *    being used are not cryptographic related :-).
37169609Sscottl * 4. If you include any Windows specific code (or a derivative thereof) from
38169609Sscottl *    the apps directory (application code) you must include an acknowledgement:
39169609Sscottl *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40169609Sscottl *
41169609Sscottl * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42169609Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43169609Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44169609Sscottl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45169609Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46169609Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47169609Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48229611Sjhb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49169609Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50169609Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51169609Sscottl * SUCH DAMAGE.
52169609Sscottl *
53252643Smarkj * The licence and distribution terms for any publically available version or
54169609Sscottl * derivative of this code cannot be changed.  i.e. this code cannot simply be
55252643Smarkj * copied and put under another distribution licence
56169609Sscottl * [including the GNU Public Licence.]
57169609Sscottl */
58169609Sscottl
59169609Sscottl#include <stdio.h>
60169609Sscottl#include <openssl/crypto.h>
61169609Sscottl#include "cryptlib.h"
62169609Sscottl#include <openssl/lhash.h>
63169609Sscottl#include <openssl/bn.h>
64169609Sscottl#include <openssl/rsa.h>
65169609Sscottl#include <openssl/rand.h>
66169609Sscottl#ifndef OPENSSL_NO_ENGINE
67169609Sscottl#include <openssl/engine.h>
68252643Smarkj#endif
69252643Smarkj
70252643Smarkjint RSA_size(const RSA *r)
71252643Smarkj	{
72252643Smarkj	return(BN_num_bytes(r->n));
73252643Smarkj	}
74169609Sscottl
75169609Sscottlint RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to,
76169609Sscottl	     RSA *rsa, int padding)
77169609Sscottl	{
78169609Sscottl#ifdef OPENSSL_FIPS
79169609Sscottl	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
80252643Smarkj			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
81169609Sscottl		{
82169609Sscottl		RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
83169609Sscottl		return -1;
84169609Sscottl		}
85169609Sscottl#endif
86169609Sscottl	return(rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding));
87169609Sscottl	}
88252643Smarkj
89169609Sscottlint RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to,
90169609Sscottl	     RSA *rsa, int padding)
91169609Sscottl	{
92243824Sdelphij#ifdef OPENSSL_FIPS
93243824Sdelphij	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
94243824Sdelphij			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
95243824Sdelphij		{
96243824Sdelphij		RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD);
97169609Sscottl		return -1;
98169609Sscottl		}
99169609Sscottl#endif
100169609Sscottl	return(rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding));
101169609Sscottl	}
102169609Sscottl
103169609Sscottlint RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to,
104169609Sscottl	     RSA *rsa, int padding)
105169609Sscottl	{
106169609Sscottl#ifdef OPENSSL_FIPS
107169609Sscottl	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
108169609Sscottl			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
109169609Sscottl		{
110169609Sscottl		RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
111204590Skib		return -1;
112169609Sscottl		}
113169609Sscottl#endif
114169609Sscottl	return(rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding));
115169609Sscottl	}
116169609Sscottl
117169609Sscottlint RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to,
118169609Sscottl	     RSA *rsa, int padding)
119169609Sscottl	{
120169609Sscottl#ifdef OPENSSL_FIPS
121169609Sscottl	if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD)
122169609Sscottl			&& !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW))
123169609Sscottl		{
124169609Sscottl		RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD);
125169609Sscottl		return -1;
126169609Sscottl		}
127169609Sscottl#endif
128169609Sscottl	return(rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding));
129169609Sscottl	}
130169609Sscottl
131169609Sscottlint RSA_flags(const RSA *r)
132169609Sscottl	{
133169609Sscottl	return((r == NULL)?0:r->meth->flags);
134169609Sscottl	}
135252643Smarkj
136169609Sscottlvoid RSA_blinding_off(RSA *rsa)
137169609Sscottl	{
138169609Sscottl	if (rsa->blinding != NULL)
139169609Sscottl		{
140169609Sscottl		BN_BLINDING_free(rsa->blinding);
141169609Sscottl		rsa->blinding=NULL;
142169609Sscottl		}
143169609Sscottl	rsa->flags &= ~RSA_FLAG_BLINDING;
144169609Sscottl	rsa->flags |= RSA_FLAG_NO_BLINDING;
145169609Sscottl	}
146169609Sscottl
147250496Ssmhint RSA_blinding_on(RSA *rsa, BN_CTX *ctx)
148169609Sscottl	{
149169609Sscottl	int ret=0;
150169609Sscottl
151169609Sscottl	if (rsa->blinding != NULL)
152252643Smarkj		RSA_blinding_off(rsa);
153252643Smarkj
154169609Sscottl	rsa->blinding = RSA_setup_blinding(rsa, ctx);
155170872Sscottl	if (rsa->blinding == NULL)
156169609Sscottl		goto err;
157169609Sscottl
158250496Ssmh	rsa->flags |= RSA_FLAG_BLINDING;
159169609Sscottl	rsa->flags &= ~RSA_FLAG_NO_BLINDING;
160250496Ssmh	ret=1;
161169609Sscottlerr:
162169609Sscottl	return(ret);
163169609Sscottl	}
164169609Sscottl
165169609Sscottlstatic BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p,
166169609Sscottl	const BIGNUM *q, BN_CTX *ctx)
167169609Sscottl{
168169609Sscottl	BIGNUM *ret = NULL, *r0, *r1, *r2;
169169609Sscottl
170169609Sscottl	if (d == NULL || p == NULL || q == NULL)
171169609Sscottl		return NULL;
172169609Sscottl
173169609Sscottl	BN_CTX_start(ctx);
174169609Sscottl	r0 = BN_CTX_get(ctx);
175169609Sscottl	r1 = BN_CTX_get(ctx);
176169609Sscottl	r2 = BN_CTX_get(ctx);
177169609Sscottl	if (r2 == NULL)
178252643Smarkj		goto err;
179252643Smarkj
180252643Smarkj	if (!BN_sub(r1, p, BN_value_one())) goto err;
181252643Smarkj	if (!BN_sub(r2, q, BN_value_one())) goto err;
182252643Smarkj	if (!BN_mul(r0, r1, r2, ctx)) goto err;
183252643Smarkj
184252643Smarkj	ret = BN_mod_inverse(NULL, d, r0, ctx);
185252643Smarkjerr:
186252643Smarkj	BN_CTX_end(ctx);
187252643Smarkj	return ret;
188169609Sscottl}
189169609Sscottl
190169609SscottlBN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
191169609Sscottl{
192250496Ssmh	BIGNUM local_n;
193169609Sscottl	BIGNUM *e,*n;
194169609Sscottl	BN_CTX *ctx;
195169609Sscottl	BN_BLINDING *ret = NULL;
196250496Ssmh
197169609Sscottl	if (in_ctx == NULL)
198250496Ssmh		{
199250496Ssmh		if ((ctx = BN_CTX_new()) == NULL) return 0;
200169609Sscottl		}
201169609Sscottl	else
202169609Sscottl		ctx = in_ctx;
203169609Sscottl
204169609Sscottl	BN_CTX_start(ctx);
205169609Sscottl	e  = BN_CTX_get(ctx);
206169609Sscottl	if (e == NULL)
207169609Sscottl		{
208169609Sscottl		RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE);
209169609Sscottl		goto err;
210169609Sscottl		}
211169609Sscottl
212169609Sscottl	if (rsa->e == NULL)
213169609Sscottl		{
214169609Sscottl		e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
215169609Sscottl		if (e == NULL)
216169609Sscottl			{
217169609Sscottl			RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT);
218169609Sscottl			goto err;
219169609Sscottl			}
220172588Sscottl		}
221169609Sscottl	else
222169609Sscottl		e = rsa->e;
223169609Sscottl
224169609Sscottl
225169609Sscottl	if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL)
226169609Sscottl		{
227169609Sscottl		/* if PRNG is not properly seeded, resort to secret
228169609Sscottl		 * exponent as unpredictable seed */
229169609Sscottl		RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0);
230169609Sscottl		}
231172588Sscottl
232172588Sscottl	if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
233169609Sscottl		{
234169609Sscottl		/* Set BN_FLG_CONSTTIME flag */
235169609Sscottl		n = &local_n;
236169609Sscottl		BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME);
237169609Sscottl		}
238169609Sscottl	else
239169609Sscottl		n = rsa->n;
240169609Sscottl
241169609Sscottl	ret = BN_BLINDING_create_param(NULL, e, n, ctx,
242169609Sscottl			rsa->meth->bn_mod_exp, rsa->_method_mod_n);
243169609Sscottl	if (ret == NULL)
244169609Sscottl		{
245169609Sscottl		RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
246172588Sscottl		goto err;
247172588Sscottl		}
248169609Sscottl	CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
249169609Sscottlerr:
250172588Sscottl	BN_CTX_end(ctx);
251172588Sscottl	if (in_ctx == NULL)
252172588Sscottl		BN_CTX_free(ctx);
253172588Sscottl	if(rsa->e == NULL)
254172588Sscottl		BN_free(e);
255172588Sscottl
256172588Sscottl	return ret;
257169609Sscottl}
258169609Sscottl