]> git.saurik.com Git - apple/security.git/blob - AppleCSP/open_ssl/rsa/rsa_eay.c
Security-163.tar.gz
[apple/security.git] / AppleCSP / open_ssl / rsa / rsa_eay.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /* crypto/rsa/rsa_eay.c */
20 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
21 * All rights reserved.
22 *
23 * This package is an SSL implementation written
24 * by Eric Young (eay@cryptsoft.com).
25 * The implementation was written so as to conform with Netscapes SSL.
26 *
27 * This library is free for commercial and non-commercial use as long as
28 * the following conditions are aheared to. The following conditions
29 * apply to all code found in this distribution, be it the RC4, RSA,
30 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
31 * included with this distribution is covered by the same copyright terms
32 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
33 *
34 * Copyright remains Eric Young's, and as such any Copyright notices in
35 * the code are not to be removed.
36 * If this package is used in a product, Eric Young should be given attribution
37 * as the author of the parts of the library used.
38 * This can be in the form of a textual message at program startup or
39 * in documentation (online or textual) provided with the package.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. All advertising materials mentioning features or use of this software
50 * must display the following acknowledgement:
51 * "This product includes cryptographic software written by
52 * Eric Young (eay@cryptsoft.com)"
53 * The word 'cryptographic' can be left out if the rouines from the library
54 * being used are not cryptographic related :-).
55 * 4. If you include any Windows specific code (or a derivative thereof) from
56 * the apps directory (application code) you must include an acknowledgement:
57 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
58 *
59 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 * The licence and distribution terms for any publically available version or
72 * derivative of this code cannot be changed. i.e. this code cannot simply be
73 * copied and put under another distribution licence
74 * [including the GNU Public Licence.]
75 */
76
77 #include <stdio.h>
78 #include "cryptlib.h"
79 #include <openssl/bn.h>
80 #include <openssl/rsa.h>
81 #include <openssl/rand.h>
82
83 #ifndef RSA_NULL
84
85 static int RSA_eay_public_encrypt(int flen, unsigned char *from,
86 unsigned char *to, RSA *rsa,int padding);
87 static int RSA_eay_private_encrypt(int flen, unsigned char *from,
88 unsigned char *to, RSA *rsa,int padding);
89 static int RSA_eay_public_decrypt(int flen, unsigned char *from,
90 unsigned char *to, RSA *rsa,int padding);
91 static int RSA_eay_private_decrypt(int flen, unsigned char *from,
92 unsigned char *to, RSA *rsa,int padding);
93 static int RSA_eay_mod_exp(BIGNUM *r0, BIGNUM *i, RSA *rsa);
94 static int RSA_eay_init(RSA *rsa);
95 static int RSA_eay_finish(RSA *rsa);
96 static const RSA_METHOD rsa_pkcs1_eay_meth={
97 "Eric Young's PKCS#1 RSA",
98 RSA_eay_public_encrypt,
99 RSA_eay_public_decrypt,
100 RSA_eay_private_encrypt,
101 RSA_eay_private_decrypt,
102 RSA_eay_mod_exp,
103 BN_mod_exp_mont,
104 RSA_eay_init,
105 RSA_eay_finish,
106 0,
107 NULL,
108 };
109
110 const RSA_METHOD *RSA_PKCS1_SSLeay(void)
111 {
112 return(&rsa_pkcs1_eay_meth);
113 }
114
115 static int RSA_eay_public_encrypt(int flen, unsigned char *from,
116 unsigned char *to, RSA *rsa, int padding)
117 {
118 BIGNUM f,ret;
119 int i,j,k,num=0,r= -1;
120 unsigned char *buf=NULL;
121 BN_CTX *ctx=NULL;
122
123 BN_init(&f);
124 BN_init(&ret);
125 if ((ctx=BN_CTX_new()) == NULL) goto err;
126 num=BN_num_bytes(rsa->n);
127 if ((buf=(unsigned char *)Malloc(num)) == NULL)
128 {
129 RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
130 goto err;
131 }
132
133 switch (padding)
134 {
135 case RSA_PKCS1_PADDING:
136 i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
137 break;
138 #ifndef _OPENSSL_APPLE_CDSA_
139 #ifndef NO_SHA
140 case RSA_PKCS1_OAEP_PADDING:
141 i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
142 break;
143 #endif
144 #endif
145 case RSA_SSLV23_PADDING:
146 i=RSA_padding_add_SSLv23(buf,num,from,flen);
147 break;
148 case RSA_NO_PADDING:
149 i=RSA_padding_add_none(buf,num,from,flen);
150 break;
151 default:
152 RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
153 goto err;
154 }
155 if (i <= 0) goto err;
156
157 if (BN_bin2bn(buf,num,&f) == NULL) goto err;
158
159 if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
160 {
161 if ((rsa->_method_mod_n=BN_MONT_CTX_new()) != NULL)
162 if (!BN_MONT_CTX_set(rsa->_method_mod_n,rsa->n,ctx))
163 goto err;
164 }
165
166 if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
167 rsa->_method_mod_n)) goto err;
168
169 /* put in leading 0 bytes if the number is less than the
170 * length of the modulus */
171 j=BN_num_bytes(&ret);
172 i=BN_bn2bin(&ret,&(to[num-j]));
173 for (k=0; k<(num-i); k++)
174 to[k]=0;
175
176 r=num;
177 err:
178 if (ctx != NULL) BN_CTX_free(ctx);
179 BN_clear_free(&f);
180 BN_clear_free(&ret);
181 if (buf != NULL)
182 {
183 memset(buf,0,num);
184 Free(buf);
185 }
186 return(r);
187 }
188
189 static int RSA_eay_private_encrypt(int flen, unsigned char *from,
190 unsigned char *to, RSA *rsa, int padding)
191 {
192 BIGNUM f,ret;
193 int i,j,k,num=0,r= -1;
194 unsigned char *buf=NULL;
195 BN_CTX *ctx=NULL;
196
197 BN_init(&f);
198 BN_init(&ret);
199
200 if ((ctx=BN_CTX_new()) == NULL) goto err;
201 num=BN_num_bytes(rsa->n);
202 if ((buf=(unsigned char *)Malloc(num)) == NULL)
203 {
204 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
205 goto err;
206 }
207
208 switch (padding)
209 {
210 case RSA_PKCS1_PADDING:
211 i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
212 break;
213 case RSA_NO_PADDING:
214 i=RSA_padding_add_none(buf,num,from,flen);
215 break;
216 case RSA_SSLV23_PADDING:
217 default:
218 RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
219 goto err;
220 }
221 if (i <= 0) goto err;
222
223 if (BN_bin2bn(buf,num,&f) == NULL) goto err;
224
225 if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL))
226 RSA_blinding_on(rsa,ctx);
227 if (rsa->flags & RSA_FLAG_BLINDING)
228 if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err;
229
230 if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
231 ((rsa->p != NULL) &&
232 (rsa->q != NULL) &&
233 (rsa->dmp1 != NULL) &&
234 (rsa->dmq1 != NULL) &&
235 (rsa->iqmp != NULL)) )
236 { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
237 else
238 {
239 if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL)) goto err;
240 }
241
242 if (rsa->flags & RSA_FLAG_BLINDING)
243 if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err;
244
245 /* put in leading 0 bytes if the number is less than the
246 * length of the modulus */
247 j=BN_num_bytes(&ret);
248 i=BN_bn2bin(&ret,&(to[num-j]));
249 for (k=0; k<(num-i); k++)
250 to[k]=0;
251
252 r=num;
253 err:
254 if (ctx != NULL) BN_CTX_free(ctx);
255 BN_clear_free(&ret);
256 BN_clear_free(&f);
257 if (buf != NULL)
258 {
259 memset(buf,0,num);
260 Free(buf);
261 }
262 return(r);
263 }
264
265 static int RSA_eay_private_decrypt(int flen, unsigned char *from,
266 unsigned char *to, RSA *rsa, int padding)
267 {
268 BIGNUM f,ret;
269 int j,num=0,r= -1;
270 unsigned char *p;
271 unsigned char *buf=NULL;
272 BN_CTX *ctx=NULL;
273
274 BN_init(&f);
275 BN_init(&ret);
276 ctx=BN_CTX_new();
277 if (ctx == NULL) goto err;
278
279 num=BN_num_bytes(rsa->n);
280
281 if ((buf=(unsigned char *)Malloc(num)) == NULL)
282 {
283 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
284 goto err;
285 }
286
287 /* This check was for equality but PGP does evil things
288 * and chops off the top '0' bytes */
289 if (flen > num)
290 {
291 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
292 goto err;
293 }
294
295 /* make data into a big number */
296 if (BN_bin2bn(from,(int)flen,&f) == NULL) goto err;
297
298 if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL))
299 RSA_blinding_on(rsa,ctx);
300 if (rsa->flags & RSA_FLAG_BLINDING)
301 if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err;
302
303 /* do the decrypt */
304 if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
305 ((rsa->p != NULL) &&
306 (rsa->q != NULL) &&
307 (rsa->dmp1 != NULL) &&
308 (rsa->dmq1 != NULL) &&
309 (rsa->iqmp != NULL)) )
310 { if (!rsa->meth->rsa_mod_exp(&ret,&f,rsa)) goto err; }
311 else
312 {
313 if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->d,rsa->n,ctx,NULL))
314 goto err;
315 }
316
317 if (rsa->flags & RSA_FLAG_BLINDING)
318 if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err;
319
320 p=buf;
321 j=BN_bn2bin(&ret,p); /* j is only used with no-padding mode */
322
323 switch (padding)
324 {
325 case RSA_PKCS1_PADDING:
326 r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
327 break;
328 #ifndef _OPENSSL_APPLE_CDSA_
329 #ifndef NO_SHA
330 case RSA_PKCS1_OAEP_PADDING:
331 r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
332 break;
333 #endif
334 #endif
335 case RSA_SSLV23_PADDING:
336 r=RSA_padding_check_SSLv23(to,num,buf,j,num);
337 break;
338 case RSA_NO_PADDING:
339 r=RSA_padding_check_none(to,num,buf,j,num);
340 break;
341 default:
342 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
343 goto err;
344 }
345 if (r < 0)
346 RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
347
348 err:
349 if (ctx != NULL) BN_CTX_free(ctx);
350 BN_clear_free(&f);
351 BN_clear_free(&ret);
352 if (buf != NULL)
353 {
354 memset(buf,0,num);
355 Free(buf);
356 }
357 return(r);
358 }
359
360 static int RSA_eay_public_decrypt(int flen, unsigned char *from,
361 unsigned char *to, RSA *rsa, int padding)
362 {
363 BIGNUM f,ret;
364 int i,num=0,r= -1;
365 unsigned char *p;
366 unsigned char *buf=NULL;
367 BN_CTX *ctx=NULL;
368
369 BN_init(&f);
370 BN_init(&ret);
371 ctx=BN_CTX_new();
372 if (ctx == NULL) goto err;
373
374 num=BN_num_bytes(rsa->n);
375 buf=(unsigned char *)Malloc(num);
376 if (buf == NULL)
377 {
378 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
379 goto err;
380 }
381
382 /* This check was for equality but PGP does evil things
383 * and chops off the top '0' bytes */
384 if (flen > num)
385 {
386 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
387 goto err;
388 }
389
390 if (BN_bin2bn(from,flen,&f) == NULL) goto err;
391 /* do the decrypt */
392 if ((rsa->_method_mod_n == NULL) && (rsa->flags & RSA_FLAG_CACHE_PUBLIC))
393 {
394 if ((rsa->_method_mod_n=BN_MONT_CTX_new()) != NULL)
395 if (!BN_MONT_CTX_set(rsa->_method_mod_n,rsa->n,ctx))
396 goto err;
397 }
398
399 if (!rsa->meth->bn_mod_exp(&ret,&f,rsa->e,rsa->n,ctx,
400 rsa->_method_mod_n)) goto err;
401
402 p=buf;
403 i=BN_bn2bin(&ret,p);
404
405 switch (padding)
406 {
407 case RSA_PKCS1_PADDING:
408 r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
409 break;
410 case RSA_NO_PADDING:
411 r=RSA_padding_check_none(to,num,buf,i,num);
412 break;
413 default:
414 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
415 goto err;
416 }
417 if (r < 0)
418 RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
419
420 err:
421 if (ctx != NULL) BN_CTX_free(ctx);
422 BN_clear_free(&f);
423 BN_clear_free(&ret);
424 if (buf != NULL)
425 {
426 memset(buf,0,num);
427 Free(buf);
428 }
429 return(r);
430 }
431
432 static int RSA_eay_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa)
433 {
434 BIGNUM r1,m1;
435 int ret=0;
436 BN_CTX *ctx;
437
438 if ((ctx=BN_CTX_new()) == NULL) goto err;
439 BN_init(&m1);
440 BN_init(&r1);
441
442 if (rsa->flags & RSA_FLAG_CACHE_PRIVATE)
443 {
444 if (rsa->_method_mod_p == NULL)
445 {
446 if ((rsa->_method_mod_p=BN_MONT_CTX_new()) != NULL)
447 if (!BN_MONT_CTX_set(rsa->_method_mod_p,rsa->p,
448 ctx))
449 goto err;
450 }
451 if (rsa->_method_mod_q == NULL)
452 {
453 if ((rsa->_method_mod_q=BN_MONT_CTX_new()) != NULL)
454 if (!BN_MONT_CTX_set(rsa->_method_mod_q,rsa->q,
455 ctx))
456 goto err;
457 }
458 }
459
460 if (!BN_mod(&r1,I,rsa->q,ctx)) goto err;
461 if (!rsa->meth->bn_mod_exp(&m1,&r1,rsa->dmq1,rsa->q,ctx,
462 rsa->_method_mod_q)) goto err;
463
464 if (!BN_mod(&r1,I,rsa->p,ctx)) goto err;
465 if (!rsa->meth->bn_mod_exp(r0,&r1,rsa->dmp1,rsa->p,ctx,
466 rsa->_method_mod_p)) goto err;
467
468 if (!BN_sub(r0,r0,&m1)) goto err;
469 /* This will help stop the size of r0 increasing, which does
470 * affect the multiply if it optimised for a power of 2 size */
471 if (r0->neg)
472 if (!BN_add(r0,r0,rsa->p)) goto err;
473
474 if (!BN_mul(&r1,r0,rsa->iqmp,ctx)) goto err;
475 if (!BN_mod(r0,&r1,rsa->p,ctx)) goto err;
476 /* If p < q it is occasionally possible for the correction of
477 * adding 'p' if r0 is negative above to leave the result still
478 * negative. This can break the private key operations: the following
479 * second correction should *always* correct this rare occurrence.
480 * This will *never* happen with OpenSSL generated keys because
481 * they ensure p > q [steve]
482 */
483 if (r0->neg)
484 if (!BN_add(r0,r0,rsa->p)) goto err;
485 if (!BN_mul(&r1,r0,rsa->q,ctx)) goto err;
486 if (!BN_add(r0,&r1,&m1)) goto err;
487
488 ret=1;
489 err:
490 BN_clear_free(&m1);
491 BN_clear_free(&r1);
492 BN_CTX_free(ctx);
493 return(ret);
494 }
495
496 static int RSA_eay_init(RSA *rsa)
497 {
498 rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
499 return(1);
500 }
501
502 static int RSA_eay_finish(RSA *rsa)
503 {
504 if (rsa->_method_mod_n != NULL)
505 BN_MONT_CTX_free(rsa->_method_mod_n);
506 if (rsa->_method_mod_p != NULL)
507 BN_MONT_CTX_free(rsa->_method_mod_p);
508 if (rsa->_method_mod_q != NULL)
509 BN_MONT_CTX_free(rsa->_method_mod_q);
510 return(1);
511 }
512
513 #endif