source: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/rsa.c

Last change on this file was 167, checked in by coas-nagasima, 7 years ago

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 22.5 KB
Line 
1/* rsa.c
2 *
3 * Copyright (C) 2006-2015 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL. (formerly known as CyaSSL)
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#ifdef HAVE_CONFIG_H
23 #include <config.h>
24#endif
25
26#include <wolfssl/wolfcrypt/settings.h>
27
28#ifndef NO_RSA
29
30#include <wolfssl/wolfcrypt/rsa.h>
31
32#ifdef HAVE_FIPS
33int wc_InitRsaKey(RsaKey* key, void* ptr)
34{
35 return InitRsaKey_fips(key, ptr);
36}
37
38
39int wc_FreeRsaKey(RsaKey* key)
40{
41 return FreeRsaKey_fips(key);
42}
43
44
45int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
46 word32 outLen, RsaKey* key, WC_RNG* rng)
47{
48 return RsaPublicEncrypt_fips(in, inLen, out, outLen, key, rng);
49}
50
51
52int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,
53 RsaKey* key)
54{
55 return RsaPrivateDecryptInline_fips(in, inLen, out, key);
56}
57
58
59int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
60 word32 outLen, RsaKey* key)
61{
62 return RsaPrivateDecrypt_fips(in, inLen, out, outLen, key);
63}
64
65
66int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
67 word32 outLen, RsaKey* key, WC_RNG* rng)
68{
69 return RsaSSL_Sign_fips(in, inLen, out, outLen, key, rng);
70}
71
72
73int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
74{
75 return RsaSSL_VerifyInline_fips(in, inLen, out, key);
76}
77
78
79int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
80 word32 outLen, RsaKey* key)
81{
82 return RsaSSL_Verify_fips(in, inLen, out, outLen, key);
83}
84
85
86int wc_RsaEncryptSize(RsaKey* key)
87{
88 return RsaEncryptSize_fips(key);
89}
90
91
92int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,
93 word32* bSz)
94{
95 /* not specified as fips so not needing _fips */
96 return RsaFlattenPublicKey(key, a, aSz, b, bSz);
97}
98#ifdef WOLFSSL_KEY_GEN
99 int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
100 {
101 return MakeRsaKey(key, size, e, rng);
102 }
103#endif
104
105
106#ifdef HAVE_CAVIUM
107 int wc_RsaInitCavium(RsaKey* key, int i)
108 {
109 return RsaInitCavium(key, i);
110 }
111
112
113 void wc_RsaFreeCavium(RsaKey* key)
114 {
115 RsaFreeCavium(key);
116 }
117#endif
118
119/* these are functions in asn and are routed to wolfssl/wolfcrypt/asn.c
120* wc_RsaPrivateKeyDecode
121* wc_RsaPublicKeyDecode
122*/
123
124#else /* else build without fips */
125#include <wolfssl/wolfcrypt/random.h>
126#include <wolfssl/wolfcrypt/error-crypt.h>
127#include <wolfssl/wolfcrypt/logging.h>
128#ifdef NO_INLINE
129 #include <wolfssl/wolfcrypt/misc.h>
130#else
131 #include <wolfcrypt/src/misc.c>
132#endif
133
134#ifdef HAVE_CAVIUM
135 static int InitCaviumRsaKey(RsaKey* key, void* heap);
136 static int FreeCaviumRsaKey(RsaKey* key);
137 static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
138 word32 outLen, RsaKey* key);
139 static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
140 word32 outLen, RsaKey* key);
141 static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,
142 word32 outLen, RsaKey* key);
143 static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,
144 word32 outLen, RsaKey* key);
145#endif
146
147enum {
148 RSA_PUBLIC_ENCRYPT = 0,
149 RSA_PUBLIC_DECRYPT = 1,
150 RSA_PRIVATE_ENCRYPT = 2,
151 RSA_PRIVATE_DECRYPT = 3,
152
153 RSA_BLOCK_TYPE_1 = 1,
154 RSA_BLOCK_TYPE_2 = 2,
155
156 RSA_MIN_SIZE = 512,
157 RSA_MAX_SIZE = 4096,
158
159 RSA_MIN_PAD_SZ = 11 /* seperator + 0 + pad value + 8 pads */
160};
161
162
163int wc_InitRsaKey(RsaKey* key, void* heap)
164{
165#ifdef HAVE_CAVIUM
166 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
167 return InitCaviumRsaKey(key, heap);
168#endif
169
170 key->type = -1; /* haven't decided yet */
171 key->heap = heap;
172
173/* TomsFastMath doesn't use memory allocation */
174#ifndef USE_FAST_MATH
175 key->n.dp = key->e.dp = 0; /* public alloc parts */
176
177 key->d.dp = key->p.dp = 0; /* private alloc parts */
178 key->q.dp = key->dP.dp = 0;
179 key->u.dp = key->dQ.dp = 0;
180#else
181 mp_init(&key->n);
182 mp_init(&key->e);
183 mp_init(&key->d);
184 mp_init(&key->p);
185 mp_init(&key->q);
186 mp_init(&key->dP);
187 mp_init(&key->dQ);
188 mp_init(&key->u);
189#endif
190
191 return 0;
192}
193
194
195int wc_FreeRsaKey(RsaKey* key)
196{
197 (void)key;
198
199#ifdef HAVE_CAVIUM
200 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
201 return FreeCaviumRsaKey(key);
202#endif
203
204/* TomsFastMath doesn't use memory allocation */
205#ifndef USE_FAST_MATH
206 if (key->type == RSA_PRIVATE) {
207 mp_clear(&key->u);
208 mp_clear(&key->dQ);
209 mp_clear(&key->dP);
210 mp_clear(&key->q);
211 mp_clear(&key->p);
212 mp_clear(&key->d);
213 }
214 mp_clear(&key->e);
215 mp_clear(&key->n);
216#endif
217
218 return 0;
219}
220
221static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
222 word32 pkcsBlockLen, byte padValue, WC_RNG* rng)
223{
224 if (inputLen == 0)
225 return 0;
226
227 pkcsBlock[0] = 0x0; /* set first byte to zero and advance */
228 pkcsBlock++; pkcsBlockLen--;
229 pkcsBlock[0] = padValue; /* insert padValue */
230
231 if (padValue == RSA_BLOCK_TYPE_1)
232 /* pad with 0xff bytes */
233 XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
234 else {
235 /* pad with non-zero random bytes */
236 word32 padLen = pkcsBlockLen - inputLen - 1, i;
237 int ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);
238
239 if (ret != 0)
240 return ret;
241
242 /* remove zeros */
243 for (i = 1; i < padLen; i++)
244 if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
245 }
246
247 pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */
248 XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
249
250 return 0;
251}
252
253
254/* UnPad plaintext, set start to *output, return length of plaintext,
255 * < 0 on error */
256static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
257 byte **output, byte padValue)
258{
259 word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0,
260 invalid = 0,
261 i = 1,
262 outputLen;
263
264 if (pkcsBlock[0] != 0x0) /* skip past zero */
265 invalid = 1;
266 pkcsBlock++; pkcsBlockLen--;
267
268 /* Require block type padValue */
269 invalid = (pkcsBlock[0] != padValue) || invalid;
270
271 /* verify the padding until we find the separator */
272 if (padValue == RSA_BLOCK_TYPE_1) {
273 while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
274 }
275 else {
276 while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
277 }
278
279 if(!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
280 WOLFSSL_MSG("RsaUnPad error, bad formatting");
281 return RSA_PAD_E;
282 }
283
284 outputLen = pkcsBlockLen - i;
285 invalid = (outputLen > maxOutputLen) || invalid;
286
287 if (invalid) {
288 WOLFSSL_MSG("RsaUnPad error, bad formatting");
289 return RSA_PAD_E;
290 }
291
292 *output = (byte *)(pkcsBlock + i);
293 return outputLen;
294}
295
296
297static int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
298 word32* outLen, int type, RsaKey* key)
299{
300 #define ERROR_OUT(x) { ret = (x); goto done;}
301
302 mp_int tmp;
303 int ret = 0;
304 word32 keyLen, len;
305
306 if (mp_init(&tmp) != MP_OKAY)
307 return MP_INIT_E;
308
309 if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
310 ERROR_OUT(MP_READ_E);
311
312 if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
313 #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */
314 if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY)
315 ERROR_OUT(MP_EXPTMOD_E);
316 #else
317 #define INNER_ERROR_OUT(x) { ret = (x); goto inner_done; }
318
319 mp_int tmpa, tmpb;
320
321 if (mp_init(&tmpa) != MP_OKAY)
322 ERROR_OUT(MP_INIT_E);
323
324 if (mp_init(&tmpb) != MP_OKAY) {
325 mp_clear(&tmpa);
326 ERROR_OUT(MP_INIT_E);
327 }
328
329 /* tmpa = tmp^dP mod p */
330 if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY)
331 INNER_ERROR_OUT(MP_EXPTMOD_E);
332
333 /* tmpb = tmp^dQ mod q */
334 if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY)
335 INNER_ERROR_OUT(MP_EXPTMOD_E);
336
337 /* tmp = (tmpa - tmpb) * qInv (mod p) */
338 if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY)
339 INNER_ERROR_OUT(MP_SUB_E);
340
341 if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY)
342 INNER_ERROR_OUT(MP_MULMOD_E);
343
344 /* tmp = tmpb + q * tmp */
345 if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY)
346 INNER_ERROR_OUT(MP_MUL_E);
347
348 if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY)
349 INNER_ERROR_OUT(MP_ADD_E);
350
351 inner_done:
352 mp_clear(&tmpa);
353 mp_clear(&tmpb);
354
355 if (ret != 0) return ret;
356
357 #endif /* RSA_LOW_MEM */
358 }
359 else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) {
360 if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
361 ERROR_OUT(MP_EXPTMOD_E);
362 }
363 else
364 ERROR_OUT(RSA_WRONG_TYPE_E);
365
366 keyLen = mp_unsigned_bin_size(&key->n);
367 if (keyLen > *outLen)
368 ERROR_OUT(RSA_BUFFER_E);
369
370 len = mp_unsigned_bin_size(&tmp);
371
372 /* pad front w/ zeros to match key length */
373 while (len < keyLen) {
374 *out++ = 0x00;
375 len++;
376 }
377
378 *outLen = keyLen;
379
380 /* convert */
381 if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
382 ERROR_OUT(MP_TO_E);
383
384done:
385 mp_clear(&tmp);
386 if (ret == MP_EXPTMOD_E) {
387 WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem");
388 }
389 return ret;
390}
391
392
393int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
394 RsaKey* key, WC_RNG* rng)
395{
396 int sz, ret;
397
398#ifdef HAVE_CAVIUM
399 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
400 return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key);
401#endif
402
403 sz = mp_unsigned_bin_size(&key->n);
404 if (sz > (int)outLen)
405 return RSA_BUFFER_E;
406
407 if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
408 return RSA_BUFFER_E;
409
410 ret = wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng);
411 if (ret != 0)
412 return ret;
413
414 if ((ret = wc_RsaFunction(out, sz, out, &outLen,
415 RSA_PUBLIC_ENCRYPT, key)) < 0)
416 sz = ret;
417
418 return sz;
419}
420
421
422int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
423{
424 int ret;
425
426#ifdef HAVE_CAVIUM
427 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) {
428 ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key);
429 if (ret > 0)
430 *out = in;
431 return ret;
432 }
433#endif
434
435 if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
436 < 0) {
437 return ret;
438 }
439
440 return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_2);
441}
442
443
444int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
445 RsaKey* key)
446{
447 int plainLen;
448 byte* tmp;
449 byte* pad = 0;
450
451#ifdef HAVE_CAVIUM
452 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
453 return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key);
454#endif
455
456 tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
457 if (tmp == NULL) {
458 return MEMORY_E;
459 }
460
461 XMEMCPY(tmp, in, inLen);
462
463 if ( (plainLen = wc_RsaPrivateDecryptInline(tmp, inLen, &pad, key) ) < 0) {
464 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
465 return plainLen;
466 }
467 if (plainLen > (int)outLen)
468 plainLen = BAD_FUNC_ARG;
469 else
470 XMEMCPY(out, pad, plainLen);
471
472 ForceZero(tmp, inLen);
473 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
474
475 return plainLen;
476}
477
478
479/* for Rsa Verify */
480int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
481{
482 int ret;
483
484#ifdef HAVE_CAVIUM
485 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC) {
486 ret = CaviumRsaSSL_Verify(in, inLen, in, inLen, key);
487 if (ret > 0)
488 *out = in;
489 return ret;
490 }
491#endif
492
493 if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key))
494 < 0) {
495 return ret;
496 }
497
498 return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1);
499}
500
501
502int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
503 RsaKey* key)
504{
505 int plainLen;
506 byte* tmp;
507 byte* pad = 0;
508
509#ifdef HAVE_CAVIUM
510 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
511 return CaviumRsaSSL_Verify(in, inLen, out, outLen, key);
512#endif
513
514 tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
515 if (tmp == NULL) {
516 return MEMORY_E;
517 }
518
519 XMEMCPY(tmp, in, inLen);
520
521 if ( (plainLen = wc_RsaSSL_VerifyInline(tmp, inLen, &pad, key) ) < 0) {
522 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
523 return plainLen;
524 }
525
526 if (plainLen > (int)outLen)
527 plainLen = BAD_FUNC_ARG;
528 else
529 XMEMCPY(out, pad, plainLen);
530
531 ForceZero(tmp, inLen);
532 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
533
534 return plainLen;
535}
536
537
538/* for Rsa Sign */
539int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
540 RsaKey* key, WC_RNG* rng)
541{
542 int sz, ret;
543
544#ifdef HAVE_CAVIUM
545 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
546 return CaviumRsaSSL_Sign(in, inLen, out, outLen, key);
547#endif
548
549 sz = mp_unsigned_bin_size(&key->n);
550 if (sz > (int)outLen)
551 return RSA_BUFFER_E;
552
553 if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
554 return RSA_BUFFER_E;
555
556 ret = wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng);
557 if (ret != 0)
558 return ret;
559
560 if ((ret = wc_RsaFunction(out, sz, out, &outLen,
561 RSA_PRIVATE_ENCRYPT,key)) < 0)
562 sz = ret;
563
564 return sz;
565}
566
567
568int wc_RsaEncryptSize(RsaKey* key)
569{
570#ifdef HAVE_CAVIUM
571 if (key->magic == WOLFSSL_RSA_CAVIUM_MAGIC)
572 return key->c_nSz;
573#endif
574 return mp_unsigned_bin_size(&key->n);
575}
576
577/* flatten RsaKey structure into individual elements (e, n) */
578int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,
579 word32* nSz)
580{
581 int sz, ret;
582
583 if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL)
584 return BAD_FUNC_ARG;
585
586 sz = mp_unsigned_bin_size(&key->e);
587 if ((word32)sz > *nSz)
588 return RSA_BUFFER_E;
589 ret = mp_to_unsigned_bin(&key->e, e);
590 if (ret != MP_OKAY)
591 return ret;
592 *eSz = (word32)sz;
593
594 sz = mp_unsigned_bin_size(&key->n);
595 if ((word32)sz > *nSz)
596 return RSA_BUFFER_E;
597 ret = mp_to_unsigned_bin(&key->n, n);
598 if (ret != MP_OKAY)
599 return ret;
600 *nSz = (word32)sz;
601
602 return 0;
603}
604
605#ifdef WOLFSSL_KEY_GEN
606/* Make an RSA key for size bits, with e specified, 65537 is a good e */
607int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
608{
609 mp_int p, q, tmp1, tmp2, tmp3;
610 int err;
611
612 if (key == NULL || rng == NULL)
613 return BAD_FUNC_ARG;
614
615 if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
616 return BAD_FUNC_ARG;
617
618 if (e < 3 || (e & 1) == 0)
619 return BAD_FUNC_ARG;
620
621 if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
622 return err;
623
624 err = mp_set_int(&tmp3, e);
625
626 /* make p */
627 if (err == MP_OKAY) {
628 do {
629 err = mp_rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */
630
631 if (err == MP_OKAY)
632 err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */
633
634 if (err == MP_OKAY)
635 err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(p-1, e) */
636 } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes p-1 */
637 }
638
639 /* make q */
640 if (err == MP_OKAY) {
641 do {
642 err = mp_rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */
643
644 if (err == MP_OKAY)
645 err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q-1 */
646
647 if (err == MP_OKAY)
648 err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(q-1, e) */
649 } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes q-1 */
650 }
651
652 if (err == MP_OKAY)
653 err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);
654
655 if (err == MP_OKAY)
656 err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
657
658 if (err == MP_OKAY)
659 err = mp_sub_d(&p, 1, &tmp2); /* tmp2 = p-1 */
660
661 if (err == MP_OKAY)
662 err = mp_lcm(&tmp1, &tmp2, &tmp1); /* tmp1 = lcm(p-1, q-1),last loop */
663
664 /* make key */
665 if (err == MP_OKAY)
666 err = mp_set_int(&key->e, e); /* key->e = e */
667
668 if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */
669 err = mp_invmod(&key->e, &tmp1, &key->d);
670
671 if (err == MP_OKAY)
672 err = mp_mul(&p, &q, &key->n); /* key->n = pq */
673
674 if (err == MP_OKAY)
675 err = mp_sub_d(&p, 1, &tmp1);
676
677 if (err == MP_OKAY)
678 err = mp_sub_d(&q, 1, &tmp2);
679
680 if (err == MP_OKAY)
681 err = mp_mod(&key->d, &tmp1, &key->dP);
682
683 if (err == MP_OKAY)
684 err = mp_mod(&key->d, &tmp2, &key->dQ);
685
686 if (err == MP_OKAY)
687 err = mp_invmod(&q, &p, &key->u);
688
689 if (err == MP_OKAY)
690 err = mp_copy(&p, &key->p);
691
692 if (err == MP_OKAY)
693 err = mp_copy(&q, &key->q);
694
695 if (err == MP_OKAY)
696 key->type = RSA_PRIVATE;
697
698 mp_clear(&tmp3);
699 mp_clear(&tmp2);
700 mp_clear(&tmp1);
701 mp_clear(&q);
702 mp_clear(&p);
703
704 if (err != MP_OKAY) {
705 wc_FreeRsaKey(key);
706 return err;
707 }
708
709 return 0;
710}
711
712
713#endif /* WOLFSSL_KEY_GEN */
714
715
716#ifdef HAVE_CAVIUM
717
718#include <cyassl/ctaocrypt/logging.h>
719#include "cavium_common.h"
720
721/* Initiliaze RSA for use with Nitrox device */
722int RsaInitCavium(RsaKey* rsa, int devId)
723{
724 if (rsa == NULL)
725 return -1;
726
727 if (CspAllocContext(CONTEXT_SSL, &rsa->contextHandle, devId) != 0)
728 return -1;
729
730 rsa->devId = devId;
731 rsa->magic = WOLFSSL_RSA_CAVIUM_MAGIC;
732
733 return 0;
734}
735
736
737/* Free RSA from use with Nitrox device */
738void wc_RsaFreeCavium(RsaKey* rsa)
739{
740 if (rsa == NULL)
741 return;
742
743 CspFreeContext(CONTEXT_SSL, rsa->contextHandle, rsa->devId);
744 rsa->magic = 0;
745}
746
747
748/* Initialize cavium RSA key */
749static int InitCaviumRsaKey(RsaKey* key, void* heap)
750{
751 if (key == NULL)
752 return BAD_FUNC_ARG;
753
754 key->heap = heap;
755 key->type = -1; /* don't know yet */
756
757 key->c_n = NULL;
758 key->c_e = NULL;
759 key->c_d = NULL;
760 key->c_p = NULL;
761 key->c_q = NULL;
762 key->c_dP = NULL;
763 key->c_dQ = NULL;
764 key->c_u = NULL;
765
766 key->c_nSz = 0;
767 key->c_eSz = 0;
768 key->c_dSz = 0;
769 key->c_pSz = 0;
770 key->c_qSz = 0;
771 key->c_dP_Sz = 0;
772 key->c_dQ_Sz = 0;
773 key->c_uSz = 0;
774
775 return 0;
776}
777
778
779/* Free cavium RSA key */
780static int FreeCaviumRsaKey(RsaKey* key)
781{
782 if (key == NULL)
783 return BAD_FUNC_ARG;
784
785 XFREE(key->c_n, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
786 XFREE(key->c_e, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
787 XFREE(key->c_d, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
788 XFREE(key->c_p, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
789 XFREE(key->c_q, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
790 XFREE(key->c_dP, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
791 XFREE(key->c_dQ, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
792 XFREE(key->c_u, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
793
794 return InitCaviumRsaKey(key, key->heap); /* reset pointers */
795}
796
797
798static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
799 word32 outLen, RsaKey* key)
800{
801 word32 requestId;
802 word32 ret;
803
804 if (key == NULL || in == NULL || out == NULL || outLen < (word32)key->c_nSz)
805 return -1;
806
807 ret = CspPkcs1v15Enc(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_eSz,
808 (word16)inLen, key->c_n, key->c_e, (byte*)in, out,
809 &requestId, key->devId);
810 if (ret != 0) {
811 WOLFSSL_MSG("Cavium Enc BT2 failed");
812 return -1;
813 }
814 return key->c_nSz;
815}
816
817
818static INLINE void ato16(const byte* c, word16* u16)
819{
820 *u16 = (c[0] << 8) | (c[1]);
821}
822
823
824static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
825 word32 outLen, RsaKey* key)
826{
827 word32 requestId;
828 word32 ret;
829 word16 outSz = (word16)outLen;
830
831 if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz)
832 return -1;
833
834 ret = CspPkcs1v15CrtDec(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_q,
835 key->c_dQ, key->c_p, key->c_dP, key->c_u,
836 (byte*)in, &outSz, out, &requestId, key->devId);
837 if (ret != 0) {
838 WOLFSSL_MSG("Cavium CRT Dec BT2 failed");
839 return -1;
840 }
841 ato16((const byte*)&outSz, &outSz);
842
843 return outSz;
844}
845
846
847static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,
848 word32 outLen, RsaKey* key)
849{
850 word32 requestId;
851 word32 ret;
852
853 if (key == NULL || in == NULL || out == NULL || inLen == 0 || outLen <
854 (word32)key->c_nSz)
855 return -1;
856
857 ret = CspPkcs1v15CrtEnc(CAVIUM_BLOCKING, BT1, key->c_nSz, (word16)inLen,
858 key->c_q, key->c_dQ, key->c_p, key->c_dP, key->c_u,
859 (byte*)in, out, &requestId, key->devId);
860 if (ret != 0) {
861 WOLFSSL_MSG("Cavium CRT Enc BT1 failed");
862 return -1;
863 }
864 return key->c_nSz;
865}
866
867
868static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,
869 word32 outLen, RsaKey* key)
870{
871 word32 requestId;
872 word32 ret;
873 word16 outSz = (word16)outLen;
874
875 if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz)
876 return -1;
877
878 ret = CspPkcs1v15Dec(CAVIUM_BLOCKING, BT1, key->c_nSz, key->c_eSz,
879 key->c_n, key->c_e, (byte*)in, &outSz, out,
880 &requestId, key->devId);
881 if (ret != 0) {
882 WOLFSSL_MSG("Cavium Dec BT1 failed");
883 return -1;
884 }
885 outSz = ntohs(outSz);
886
887 return outSz;
888}
889
890
891#endif /* HAVE_CAVIUM */
892
893#endif /* HAVE_FIPS */
894#endif /* NO_RSA */
895
Note: See TracBrowser for help on using the repository browser.