blob: 6bf681f1f9b22760e240014c6ceffb509c4e1eec [file] [log] [blame]
Ralf S. Engelschall58964a41998-12-21 10:56:39 +00001/* crypto/rsa/rsa_eay.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
60#include "cryptlib.h"
Bodo Möllerec577821999-04-23 22:13:45 +000061#include <openssl/bn.h>
62#include <openssl/rsa.h>
63#include <openssl/rand.h>
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000064
Dr. Stephen Hensonc1cd88a1999-09-08 18:19:45 +000065#ifndef RSA_NULL
66
Richard Levitte29c1f062000-11-06 22:34:17 +000067static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000068 unsigned char *to, RSA *rsa,int padding);
Richard Levitte29c1f062000-11-06 22:34:17 +000069static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000070 unsigned char *to, RSA *rsa,int padding);
Richard Levitte29c1f062000-11-06 22:34:17 +000071static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000072 unsigned char *to, RSA *rsa,int padding);
Richard Levitte29c1f062000-11-06 22:34:17 +000073static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000074 unsigned char *to, RSA *rsa,int padding);
Geoff Thorpe46ef8732004-03-25 02:52:04 +000075static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000076static int RSA_eay_init(RSA *rsa);
77static int RSA_eay_finish(RSA *rsa);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000078static RSA_METHOD rsa_pkcs1_eay_meth={
79 "Eric Young's PKCS#1 RSA",
80 RSA_eay_public_encrypt,
Bodo Möller24cff6c2001-07-25 17:02:58 +000081 RSA_eay_public_decrypt, /* signature verification */
82 RSA_eay_private_encrypt, /* signing */
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000083 RSA_eay_private_decrypt,
84 RSA_eay_mod_exp,
Bodo Möller123d24d2000-12-18 16:39:00 +000085 BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000086 RSA_eay_init,
87 RSA_eay_finish,
Bodo Möllerbe6d7702001-09-20 15:41:34 +000088 0, /* flags */
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000089 NULL,
Bodo Möllerbe6d7702001-09-20 15:41:34 +000090 0, /* rsa_sign */
Geoff Thorpe2814c622003-01-07 05:51:39 +000091 0, /* rsa_verify */
92 NULL /* rsa_keygen */
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000093 };
94
Richard Levitte7be7c2e2000-11-07 13:49:46 +000095const RSA_METHOD *RSA_PKCS1_SSLeay(void)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000096 {
97 return(&rsa_pkcs1_eay_meth);
98 }
99
Geoff Thorpe79221bc2003-02-14 23:21:19 +0000100/* Static helper to reduce oodles of code duplication. As a slight
101 * optimisation, the "MONT_HELPER() macro must be used as front-end to this
102 * function, to prevent unnecessary function calls - there is an initial test
103 * that is performed by the macro-generated code. */
104static int rsa_eay_mont_helper(BN_MONT_CTX **ptr, const BIGNUM *modulus, BN_CTX *ctx)
105 {
106 BN_MONT_CTX *bn_mont_ctx;
107 if((bn_mont_ctx = BN_MONT_CTX_new()) == NULL)
108 return 0;
109 if(!BN_MONT_CTX_set(bn_mont_ctx, modulus, ctx))
110 {
111 BN_MONT_CTX_free(bn_mont_ctx);
112 return 0;
113 }
114 if (*ptr == NULL) /* other thread may have finished first */
115 {
116 CRYPTO_w_lock(CRYPTO_LOCK_RSA);
117 if (*ptr == NULL) /* check again in the lock to stop races */
118 {
119 *ptr = bn_mont_ctx;
120 bn_mont_ctx = NULL;
121 }
122 CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
123 }
124 if (bn_mont_ctx)
125 BN_MONT_CTX_free(bn_mont_ctx);
126 return 1;
127 }
128/* Usage example;
129 * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
130 */
131#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \
132 if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \
133 !rsa_eay_mont_helper(&((rsa)->_method_mod_##m), \
134 (rsa)->m, (ctx))) \
135 err_instr
136
Richard Levitte29c1f062000-11-06 22:34:17 +0000137static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
Ulf Möller6b691a51999-04-19 21:31:43 +0000138 unsigned char *to, RSA *rsa, int padding)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000139 {
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000140 BIGNUM *f,*ret;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000141 int i,j,k,num=0,r= -1;
142 unsigned char *buf=NULL;
143 BN_CTX *ctx=NULL;
144
145 if ((ctx=BN_CTX_new()) == NULL) goto err;
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000146 BN_CTX_start(ctx);
147 f = BN_CTX_get(ctx);
148 ret = BN_CTX_get(ctx);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000149 num=BN_num_bytes(rsa->n);
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000150 buf = OPENSSL_malloc(num);
151 if (!f || !ret || !buf)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000152 {
153 RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
154 goto err;
155 }
156
157 switch (padding)
158 {
159 case RSA_PKCS1_PADDING:
160 i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
161 break;
Richard Levittecf1b7d92001-02-19 16:06:34 +0000162#ifndef OPENSSL_NO_SHA
Ben Lauriea4949891999-02-17 21:11:08 +0000163 case RSA_PKCS1_OAEP_PADDING:
164 i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
165 break;
Ulf Möller79df9d61999-04-27 03:19:12 +0000166#endif
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000167 case RSA_SSLV23_PADDING:
168 i=RSA_padding_add_SSLv23(buf,num,from,flen);
169 break;
170 case RSA_NO_PADDING:
171 i=RSA_padding_add_none(buf,num,from,flen);
172 break;
173 default:
174 RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
175 goto err;
176 }
177 if (i <= 0) goto err;
178
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000179 if (BN_bin2bn(buf,num,f) == NULL) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000180
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000181 if (BN_ucmp(f, rsa->n) >= 0)
Bodo Möller24cff6c2001-07-25 17:02:58 +0000182 {
183 /* usually the padding functions would catch this */
184 RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
185 goto err;
186 }
187
Geoff Thorpe79221bc2003-02-14 23:21:19 +0000188 MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
189
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000190 if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
Ben Laurie03f8b041998-12-29 17:22:31 +0000191 rsa->_method_mod_n)) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000192
193 /* put in leading 0 bytes if the number is less than the
194 * length of the modulus */
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000195 j=BN_num_bytes(ret);
196 i=BN_bn2bin(ret,&(to[num-j]));
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000197 for (k=0; k<(num-i); k++)
198 to[k]=0;
199
200 r=num;
201err:
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000202 if (ctx != NULL)
203 {
204 BN_CTX_end(ctx);
205 BN_CTX_free(ctx);
206 }
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000207 if (buf != NULL)
208 {
Richard Levitte45799242002-11-28 08:04:36 +0000209 OPENSSL_cleanse(buf,num);
Richard Levitte26a3a482000-06-01 22:19:21 +0000210 OPENSSL_free(buf);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000211 }
212 return(r);
213 }
214
Nils Larsch800e4002005-04-26 22:31:48 +0000215static BN_BLINDING *rsa_get_blinding(RSA *rsa, BIGNUM **r, int *local, BN_CTX *ctx)
216{
217 BN_BLINDING *ret;
Bodo Möllerc5541552003-03-20 17:31:30 +0000218
Nils Larsch800e4002005-04-26 22:31:48 +0000219 if (rsa->blinding == NULL)
Bodo Möller5679bcc2003-04-02 09:50:22 +0000220 {
Nils Larsch800e4002005-04-26 22:31:48 +0000221 if (rsa->blinding == NULL)
222 {
223 CRYPTO_w_lock(CRYPTO_LOCK_RSA);
224 if (rsa->blinding == NULL)
225 rsa->blinding = RSA_setup_blinding(rsa, ctx);
226 CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
227 }
228 }
229
230 ret = rsa->blinding;
231 if (ret == NULL)
232 return NULL;
233
234 if (BN_BLINDING_get_thread_id(ret) != CRYPTO_thread_id())
235 {
236 *local = 0;
237 if (rsa->mt_blinding == NULL)
238 {
239 CRYPTO_w_lock(CRYPTO_LOCK_RSA);
240 if (rsa->mt_blinding == NULL)
241 rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
242 CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
243 }
244 ret = rsa->mt_blinding;
Bodo Möller5679bcc2003-04-02 09:50:22 +0000245 }
246 else
Nils Larsch800e4002005-04-26 22:31:48 +0000247 *local = 1;
Bodo Möller5679bcc2003-04-02 09:50:22 +0000248
Bodo Möller5679bcc2003-04-02 09:50:22 +0000249 return ret;
Nils Larsch800e4002005-04-26 22:31:48 +0000250}
251
252static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
253 BIGNUM *r, BN_CTX *ctx)
254{
255 if (local)
256 return BN_BLINDING_convert_ex(f, NULL, b, ctx);
257 else
258 {
259 int ret;
260 CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
261 ret = BN_BLINDING_convert_ex(f, r, b, ctx);
262 CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
263 return ret;
264 }
265}
266
267static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
268 BIGNUM *r, BN_CTX *ctx)
269{
270 if (local)
271 return BN_BLINDING_invert_ex(f, NULL, b, ctx);
272 else
273 {
274 int ret;
275 CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
276 ret = BN_BLINDING_invert_ex(f, r, b, ctx);
277 CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
278 return ret;
279 }
280}
Bodo Möller5679bcc2003-04-02 09:50:22 +0000281
Bodo Möller24cff6c2001-07-25 17:02:58 +0000282/* signing */
Richard Levitte29c1f062000-11-06 22:34:17 +0000283static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
Ulf Möller6b691a51999-04-19 21:31:43 +0000284 unsigned char *to, RSA *rsa, int padding)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000285 {
Nils Larsch800e4002005-04-26 22:31:48 +0000286 BIGNUM *f, *ret, *br;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000287 int i,j,k,num=0,r= -1;
288 unsigned char *buf=NULL;
289 BN_CTX *ctx=NULL;
Bodo Möller5679bcc2003-04-02 09:50:22 +0000290 int local_blinding = 0;
291 BN_BLINDING *blinding = NULL;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000292
293 if ((ctx=BN_CTX_new()) == NULL) goto err;
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000294 BN_CTX_start(ctx);
Nils Larsch800e4002005-04-26 22:31:48 +0000295 f = BN_CTX_get(ctx);
296 br = BN_CTX_get(ctx);
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000297 ret = BN_CTX_get(ctx);
Nils Larsch800e4002005-04-26 22:31:48 +0000298 num = BN_num_bytes(rsa->n);
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000299 buf = OPENSSL_malloc(num);
300 if(!f || !ret || !buf)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000301 {
302 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
303 goto err;
304 }
305
306 switch (padding)
307 {
308 case RSA_PKCS1_PADDING:
309 i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
310 break;
311 case RSA_NO_PADDING:
312 i=RSA_padding_add_none(buf,num,from,flen);
313 break;
314 case RSA_SSLV23_PADDING:
315 default:
316 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
317 goto err;
318 }
319 if (i <= 0) goto err;
320
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000321 if (BN_bin2bn(buf,num,f) == NULL) goto err;
Bodo Möller24cff6c2001-07-25 17:02:58 +0000322
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000323 if (BN_ucmp(f, rsa->n) >= 0)
Bodo Möller24cff6c2001-07-25 17:02:58 +0000324 {
325 /* usually the padding functions would catch this */
326 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
327 goto err;
328 }
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000329
Bodo Möllerc5541552003-03-20 17:31:30 +0000330 if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
Bodo Möller5679bcc2003-04-02 09:50:22 +0000331 {
Nils Larsch800e4002005-04-26 22:31:48 +0000332 blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
Bodo Möller5679bcc2003-04-02 09:50:22 +0000333 if (blinding == NULL)
334 {
335 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
336 goto err;
337 }
338 }
339
340 if (blinding != NULL)
Nils Larsch800e4002005-04-26 22:31:48 +0000341 if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
342 goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000343
Dr. Stephen Henson770d19b1999-07-27 21:58:08 +0000344 if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
345 ((rsa->p != NULL) &&
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000346 (rsa->q != NULL) &&
347 (rsa->dmp1 != NULL) &&
348 (rsa->dmq1 != NULL) &&
Dr. Stephen Henson770d19b1999-07-27 21:58:08 +0000349 (rsa->iqmp != NULL)) )
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000350 { if (!rsa->meth->rsa_mod_exp(ret,f,rsa,ctx)) goto err; }
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000351 else
352 {
Geoff Thorpeb12753d2003-02-15 00:18:38 +0000353 MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000354 if (!rsa->meth->bn_mod_exp(ret,f,rsa->d,rsa->n,ctx,
Geoff Thorpeb12753d2003-02-15 00:18:38 +0000355 rsa->_method_mod_n)) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000356 }
357
Bodo Möller5679bcc2003-04-02 09:50:22 +0000358 if (blinding)
Nils Larsch800e4002005-04-26 22:31:48 +0000359 if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
360 goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000361
362 /* put in leading 0 bytes if the number is less than the
363 * length of the modulus */
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000364 j=BN_num_bytes(ret);
365 i=BN_bn2bin(ret,&(to[num-j]));
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000366 for (k=0; k<(num-i); k++)
367 to[k]=0;
368
369 r=num;
370err:
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000371 if (ctx != NULL)
372 {
373 BN_CTX_end(ctx);
374 BN_CTX_free(ctx);
375 }
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000376 if (buf != NULL)
377 {
Richard Levitte45799242002-11-28 08:04:36 +0000378 OPENSSL_cleanse(buf,num);
Richard Levitte26a3a482000-06-01 22:19:21 +0000379 OPENSSL_free(buf);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000380 }
381 return(r);
382 }
383
Richard Levitte29c1f062000-11-06 22:34:17 +0000384static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
Ulf Möller6b691a51999-04-19 21:31:43 +0000385 unsigned char *to, RSA *rsa, int padding)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000386 {
Nils Larsch800e4002005-04-26 22:31:48 +0000387 BIGNUM *f, *ret, *br;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000388 int j,num=0,r= -1;
389 unsigned char *p;
390 unsigned char *buf=NULL;
391 BN_CTX *ctx=NULL;
Bodo Möller5679bcc2003-04-02 09:50:22 +0000392 int local_blinding = 0;
393 BN_BLINDING *blinding = NULL;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000394
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000395 if((ctx = BN_CTX_new()) == NULL) goto err;
396 BN_CTX_start(ctx);
Nils Larsch800e4002005-04-26 22:31:48 +0000397 f = BN_CTX_get(ctx);
398 br = BN_CTX_get(ctx);
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000399 ret = BN_CTX_get(ctx);
Nils Larsch800e4002005-04-26 22:31:48 +0000400 num = BN_num_bytes(rsa->n);
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000401 buf = OPENSSL_malloc(num);
402 if(!f || !ret || !buf)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000403 {
404 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
405 goto err;
406 }
407
Ulf Möller657e60f2000-02-03 23:23:24 +0000408 /* This check was for equality but PGP does evil things
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000409 * and chops off the top '0' bytes */
410 if (flen > num)
411 {
412 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
413 goto err;
414 }
415
416 /* make data into a big number */
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000417 if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000418
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000419 if (BN_ucmp(f, rsa->n) >= 0)
Bodo Möller24cff6c2001-07-25 17:02:58 +0000420 {
421 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
422 goto err;
423 }
424
Bodo Möllerc5541552003-03-20 17:31:30 +0000425 if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
Bodo Möller5679bcc2003-04-02 09:50:22 +0000426 {
Nils Larsch800e4002005-04-26 22:31:48 +0000427 blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
Bodo Möller5679bcc2003-04-02 09:50:22 +0000428 if (blinding == NULL)
429 {
Nils Larsch800e4002005-04-26 22:31:48 +0000430 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
Bodo Möller5679bcc2003-04-02 09:50:22 +0000431 goto err;
432 }
433 }
434
435 if (blinding != NULL)
Nils Larsch800e4002005-04-26 22:31:48 +0000436 if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
437 goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000438
439 /* do the decrypt */
Dr. Stephen Henson770d19b1999-07-27 21:58:08 +0000440 if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
441 ((rsa->p != NULL) &&
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000442 (rsa->q != NULL) &&
443 (rsa->dmp1 != NULL) &&
444 (rsa->dmq1 != NULL) &&
Dr. Stephen Henson770d19b1999-07-27 21:58:08 +0000445 (rsa->iqmp != NULL)) )
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000446 { if (!rsa->meth->rsa_mod_exp(ret,f,rsa,ctx)) goto err; }
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000447 else
448 {
Geoff Thorpeb12753d2003-02-15 00:18:38 +0000449 MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000450 if (!rsa->meth->bn_mod_exp(ret,f,rsa->d,rsa->n,ctx,
Geoff Thorpeb12753d2003-02-15 00:18:38 +0000451 rsa->_method_mod_n))
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000452 goto err;
453 }
454
Bodo Möller5679bcc2003-04-02 09:50:22 +0000455 if (blinding)
Nils Larsch800e4002005-04-26 22:31:48 +0000456 if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
457 goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000458
459 p=buf;
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000460 j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000461
462 switch (padding)
463 {
464 case RSA_PKCS1_PADDING:
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000465 r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000466 break;
Richard Levittecf1b7d92001-02-19 16:06:34 +0000467#ifndef OPENSSL_NO_SHA
Ben Lauriea4949891999-02-17 21:11:08 +0000468 case RSA_PKCS1_OAEP_PADDING:
469 r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
470 break;
Ulf Möller79df9d61999-04-27 03:19:12 +0000471#endif
Ben Lauriea4949891999-02-17 21:11:08 +0000472 case RSA_SSLV23_PADDING:
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000473 r=RSA_padding_check_SSLv23(to,num,buf,j,num);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000474 break;
475 case RSA_NO_PADDING:
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000476 r=RSA_padding_check_none(to,num,buf,j,num);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000477 break;
478 default:
479 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
480 goto err;
481 }
482 if (r < 0)
483 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
484
485err:
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000486 if (ctx != NULL)
487 {
488 BN_CTX_end(ctx);
489 BN_CTX_free(ctx);
490 }
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000491 if (buf != NULL)
492 {
Richard Levitte45799242002-11-28 08:04:36 +0000493 OPENSSL_cleanse(buf,num);
Richard Levitte26a3a482000-06-01 22:19:21 +0000494 OPENSSL_free(buf);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000495 }
496 return(r);
497 }
498
Bodo Möller24cff6c2001-07-25 17:02:58 +0000499/* signature verification */
Richard Levitte29c1f062000-11-06 22:34:17 +0000500static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
Ulf Möller6b691a51999-04-19 21:31:43 +0000501 unsigned char *to, RSA *rsa, int padding)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000502 {
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000503 BIGNUM *f,*ret;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000504 int i,num=0,r= -1;
505 unsigned char *p;
506 unsigned char *buf=NULL;
507 BN_CTX *ctx=NULL;
508
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000509 if((ctx = BN_CTX_new()) == NULL) goto err;
510 BN_CTX_start(ctx);
511 f = BN_CTX_get(ctx);
512 ret = BN_CTX_get(ctx);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000513 num=BN_num_bytes(rsa->n);
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000514 buf = OPENSSL_malloc(num);
515 if(!f || !ret || !buf)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000516 {
517 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
518 goto err;
519 }
520
Ulf Möller657e60f2000-02-03 23:23:24 +0000521 /* This check was for equality but PGP does evil things
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000522 * and chops off the top '0' bytes */
523 if (flen > num)
524 {
525 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
526 goto err;
527 }
528
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000529 if (BN_bin2bn(from,flen,f) == NULL) goto err;
Bodo Möller24cff6c2001-07-25 17:02:58 +0000530
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000531 if (BN_ucmp(f, rsa->n) >= 0)
Bodo Möller24cff6c2001-07-25 17:02:58 +0000532 {
533 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
534 goto err;
535 }
536
Geoff Thorpe79221bc2003-02-14 23:21:19 +0000537 MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
538
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000539 if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
Ben Laurie03f8b041998-12-29 17:22:31 +0000540 rsa->_method_mod_n)) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000541
542 p=buf;
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000543 i=BN_bn2bin(ret,p);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000544
545 switch (padding)
546 {
547 case RSA_PKCS1_PADDING:
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000548 r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000549 break;
550 case RSA_NO_PADDING:
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000551 r=RSA_padding_check_none(to,num,buf,i,num);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000552 break;
553 default:
554 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
555 goto err;
556 }
557 if (r < 0)
558 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
559
560err:
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000561 if (ctx != NULL)
562 {
563 BN_CTX_end(ctx);
564 BN_CTX_free(ctx);
565 }
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000566 if (buf != NULL)
567 {
Richard Levitte45799242002-11-28 08:04:36 +0000568 OPENSSL_cleanse(buf,num);
Richard Levitte26a3a482000-06-01 22:19:21 +0000569 OPENSSL_free(buf);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000570 }
571 return(r);
572 }
573
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000574static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000575 {
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000576 BIGNUM *r1,*m1,*vrfy;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000577 int ret=0;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000578
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000579 BN_CTX_start(ctx);
580 r1 = BN_CTX_get(ctx);
581 m1 = BN_CTX_get(ctx);
582 vrfy = BN_CTX_get(ctx);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000583
Geoff Thorpe79221bc2003-02-14 23:21:19 +0000584 MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
585 MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
Geoff Thorpeb12753d2003-02-15 00:18:38 +0000586 MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
Bodo Möller126fe082000-12-19 12:31:41 +0000587
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000588 if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
589 if (!rsa->meth->bn_mod_exp(m1,r1,rsa->dmq1,rsa->q,ctx,
Ben Laurie03f8b041998-12-29 17:22:31 +0000590 rsa->_method_mod_q)) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000591
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000592 if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
593 if (!rsa->meth->bn_mod_exp(r0,r1,rsa->dmp1,rsa->p,ctx,
Ben Laurie03f8b041998-12-29 17:22:31 +0000594 rsa->_method_mod_p)) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000595
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000596 if (!BN_sub(r0,r0,m1)) goto err;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000597 /* This will help stop the size of r0 increasing, which does
598 * affect the multiply if it optimised for a power of 2 size */
Nils Larschff22e912005-04-22 20:02:44 +0000599 if (BN_is_negative(r0))
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000600 if (!BN_add(r0,r0,rsa->p)) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000601
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000602 if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
603 if (!BN_mod(r0,r1,rsa->p,ctx)) goto err;
Dr. Stephen Hensonabd4c911999-03-11 02:42:13 +0000604 /* If p < q it is occasionally possible for the correction of
605 * adding 'p' if r0 is negative above to leave the result still
606 * negative. This can break the private key operations: the following
607 * second correction should *always* correct this rare occurrence.
608 * This will *never* happen with OpenSSL generated keys because
609 * they ensure p > q [steve]
610 */
Nils Larschff22e912005-04-22 20:02:44 +0000611 if (BN_is_negative(r0))
Dr. Stephen Hensonabd4c911999-03-11 02:42:13 +0000612 if (!BN_add(r0,r0,rsa->p)) goto err;
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000613 if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
614 if (!BN_add(r0,r1,m1)) goto err;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000615
Ulf Möller6a5b52e2001-03-28 04:56:58 +0000616 if (rsa->e && rsa->n)
617 {
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000618 if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
Geoff Thorpe81d19982001-07-20 15:16:10 +0000619 /* If 'I' was greater than (or equal to) rsa->n, the operation
620 * will be equivalent to using 'I mod n'. However, the result of
621 * the verify will *always* be less than 'n' so we don't check
622 * for absolute equality, just congruency. */
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000623 if (!BN_sub(vrfy, vrfy, I)) goto err;
624 if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
Nils Larschff22e912005-04-22 20:02:44 +0000625 if (BN_is_negative(vrfy))
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000626 if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
627 if (!BN_is_zero(vrfy))
Geoff Thorpe81d19982001-07-20 15:16:10 +0000628 /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
629 * miscalculated CRT output, just do a raw (slower)
630 * mod_exp and return that instead. */
Geoff Thorpeb12753d2003-02-15 00:18:38 +0000631 if (!rsa->meth->bn_mod_exp(r0,I,rsa->d,rsa->n,ctx,
632 rsa->_method_mod_n)) goto err;
Ulf Möller6a5b52e2001-03-28 04:56:58 +0000633 }
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000634 ret=1;
635err:
Geoff Thorpe46ef8732004-03-25 02:52:04 +0000636 BN_CTX_end(ctx);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000637 return(ret);
638 }
639
Ulf Möller6b691a51999-04-19 21:31:43 +0000640static int RSA_eay_init(RSA *rsa)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000641 {
642 rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
643 return(1);
644 }
645
Ulf Möller6b691a51999-04-19 21:31:43 +0000646static int RSA_eay_finish(RSA *rsa)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000647 {
Ben Laurie03f8b041998-12-29 17:22:31 +0000648 if (rsa->_method_mod_n != NULL)
649 BN_MONT_CTX_free(rsa->_method_mod_n);
650 if (rsa->_method_mod_p != NULL)
651 BN_MONT_CTX_free(rsa->_method_mod_p);
652 if (rsa->_method_mod_q != NULL)
653 BN_MONT_CTX_free(rsa->_method_mod_q);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000654 return(1);
655 }
656
Dr. Stephen Hensonc1cd88a1999-09-08 18:19:45 +0000657#endif