1 /* rsa.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
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-1335, USA
20 */
21
22
23 #ifdef HAVE_CONFIG_H /* configure options when using autoconf */
24 #include <config.h>
25 #endif
26
27 #include <wolfssl/options.h>
28 #include <wolfssl/wolfcrypt/settings.h>
29
30 #ifndef NO_RSA
31
32 #define USER_CRYPTO_ERROR -101
33
34 #ifdef OPENSSL_EXTRA
35 #include <wolfssl/openssl/rsa.h> /* include for openssl compatibility */
36 #include <wolfssl/openssl/bn.h>
37 #endif
38 #include "user_rsa.h"
39
40 #ifdef DEBUG_WOLFSSL /* debug done without variadric to allow older compilers */
41 #include <stdio.h>
42 #define USER_DEBUG(x) printf x
43 #else
44 #define USER_DEBUG(x)
45 #endif
46
47 #define ASN_INTEGER 0x02
48 #define ASN_BIT_STRING 0x03
49 #define ASN_TAG_NULL 0x05
50 #define ASN_OBJECT_ID 0x06
51
52
53 /* Make sure compiler doesn't skip -- used from wolfSSL */
ForceZero(const void * mem,word32 len)54 static inline void ForceZero(const void* mem, word32 len)
55 {
56 volatile byte* z = (volatile byte*)mem;
57
58 while (len--) *z++ = 0;
59 }
60
61 enum {
62 RSA_PUBLIC_ENCRYPT = 0,
63 RSA_PUBLIC_DECRYPT = 1,
64 RSA_PRIVATE_ENCRYPT = 2,
65 RSA_PRIVATE_DECRYPT = 3,
66
67 RSA_BLOCK_TYPE_1 = 1,
68 RSA_BLOCK_TYPE_2 = 2,
69
70 RSA_MIN_SIZE = 512,
71 RSA_MAX_SIZE = 4096, /* max allowed in IPP library */
72
73 RSA_MIN_PAD_SZ = 11 /* separator + 0 + pad value + 8 pads */
74 };
75
76
wc_InitRsaKey_ex(RsaKey * key,void * heap,int devId)77 int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId)
78 {
79
80 USER_DEBUG(("Entering wc_InitRsaKey\n"));
81
82 if (key == NULL)
83 return USER_CRYPTO_ERROR;
84
85 /* set full struct as 0 */
86 ForceZero(key, sizeof(RsaKey));
87
88 USER_DEBUG(("\tExit wc_InitRsaKey\n"));
89
90 (void)devId;
91 (void)heap;
92 return 0;
93 }
94
wc_InitRsaKey(RsaKey * key,void * heap)95 int wc_InitRsaKey(RsaKey* key, void* heap)
96 {
97 return wc_InitRsaKey_ex(key, heap, INVALID_DEVID);
98 }
99
100
101 /* three functions needed for cert and key gen */
102 #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)
103 /* return 1 if there is a leading bit*/
wc_Rsa_leading_bit(void * bn)104 int wc_Rsa_leading_bit(void* bn)
105 {
106 int ret = 0;
107 int dataSz;
108 Ipp32u* data;
109 Ipp32u q;
110 int qSz = sizeof(Ipp32u);
111
112 if (ippsExtGet_BN(NULL, &dataSz, NULL, bn) != ippStsNoErr) {
113 USER_DEBUG(("ippsExtGet_BN Rsa leading bit error\n"));
114 return USER_CRYPTO_ERROR;
115 }
116
117 /* convert from size in binary to Ipp32u */
118 dataSz = dataSz / 32 + ((dataSz % 32)? 1 : 0);
119 data = (Ipp32u*)XMALLOC(dataSz * sizeof(Ipp32u), NULL,
120 DYNAMIC_TYPE_USER_CRYPTO);
121 if (data == NULL) {
122 USER_DEBUG(("Rsa leading bit memory error\n"));
123 return 0;
124 }
125
126 /* extract value from BN */
127 if (ippsExtGet_BN(NULL, NULL, data, bn) != ippStsNoErr) {
128 USER_DEBUG(("Rsa leading bit error\n"));
129 XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
130 return 0;
131 }
132
133 /* use method like what's used in wolfssl tfm.c */
134 q = data[dataSz - 1];
135
136 ret = 0;
137 while (qSz > 0) {
138 if (q != 0)
139 ret = (q & 0x80) != 0;
140 q >>= 8;
141 qSz--;
142 }
143
144 XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
145
146 return ret;
147 }
148
149
150 /* get the size in bytes of BN */
wc_Rsa_unsigned_bin_size(void * bn)151 int wc_Rsa_unsigned_bin_size(void* bn)
152 {
153 int ret = 0;
154 if (ippsExtGet_BN(NULL, &ret, NULL, bn) != ippStsNoErr) {
155 USER_DEBUG(("Rsa unsigned bin size error\n"));
156 return USER_CRYPTO_ERROR;
157 }
158 return (ret / 8) + ((ret % 8)? 1: 0); /* size in bytes */
159 }
160
161 #ifndef MP_OKAY
162 #define MP_OKAY 0
163 #endif
164
165 /* extract the bn value to a unsigned byte array and return MP_OKAY on success */
wc_Rsa_to_unsigned_bin(void * bn,byte * in,int inLen)166 int wc_Rsa_to_unsigned_bin(void* bn, byte* in, int inLen)
167 {
168 if (ippsGetOctString_BN((Ipp8u*)in, inLen, bn) != ippStsNoErr) {
169 USER_DEBUG(("Rsa to unsigned bin error\n"));
170 return USER_CRYPTO_ERROR;
171 }
172 return MP_OKAY;
173 }
174 #endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN || OPENSSL_EXTRA */
175
176
177 #ifdef OPENSSL_EXTRA /* functions needed for openssl compatibility layer */
SetIndividualExternal(WOLFSSL_BIGNUM ** bn,IppsBigNumState * in)178 static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, IppsBigNumState* in)
179 {
180 IppStatus ret;
181 byte* data;
182 int sz;
183
184 USER_DEBUG(("Entering SetIndividualExternal\n"));
185
186 if (bn == NULL || in == NULL) {
187 USER_DEBUG(("inputs NULL error\n"));
188 return USER_CRYPTO_ERROR;
189 }
190
191 if (*bn == NULL) {
192 *bn = wolfSSL_BN_new();
193 if (*bn == NULL) {
194 USER_DEBUG(("SetIndividualExternal alloc failed\n"));
195 return USER_CRYPTO_ERROR;
196 }
197 }
198
199 /* get size of array needed and extract oct array of data */
200 ret = ippsGetSize_BN(in, &sz);
201 if (ret != ippStsNoErr)
202 return USER_CRYPTO_ERROR;
203
204 data = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_USER_CRYPTO);
205 if (data == NULL)
206 return USER_CRYPTO_ERROR;
207
208 ret = ippsGetOctString_BN(data, sz, in);
209 if (ret != ippStsNoErr) {
210 XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
211 return USER_CRYPTO_ERROR;
212 }
213
214 /* store the data into a wolfSSL Big Number */
215 *bn = wolfSSL_BN_bin2bn(data, sz, *bn);
216
217 XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
218
219 return 0;
220 }
221
222
SetIndividualInternal(WOLFSSL_BIGNUM * bn,IppsBigNumState ** mpi)223 static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, IppsBigNumState** mpi)
224 {
225 int length, ctxSz, sz;
226 IppStatus ret;
227 Ipp8u* data;
228
229 USER_DEBUG(("Entering SetIndividualInternal\n"));
230
231 if (bn == NULL || bn->internal == NULL) {
232 USER_DEBUG(("bn NULL error\n"));
233 return USER_CRYPTO_ERROR;
234 }
235
236 length = wolfSSL_BN_num_bytes(bn);
237
238 /* if not IPP BN then create one */
239 if (*mpi == NULL) {
240 ret = ippsBigNumGetSize(length, &ctxSz);
241 if (ret != ippStsNoErr)
242 return USER_CRYPTO_ERROR;
243
244 *mpi = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
245 if (*mpi == NULL)
246 return USER_CRYPTO_ERROR;
247
248 ret = ippsBigNumInit(length, *mpi);
249 if (ret != ippStsNoErr) {
250 XFREE(*mpi, NULL, DYNAMIC_TYPE_USER_CRYPTO);
251 return USER_CRYPTO_ERROR;
252 }
253
254 }
255
256 /* get the size of array needed and check IPP BigNum */
257 if (ippsGetSize_BN(*mpi, &sz) != ippStsNoErr)
258 return USER_CRYPTO_ERROR;
259
260 if (sz < length) {
261 USER_DEBUG(("big num size is too small\n"));
262 return USER_CRYPTO_ERROR;
263 }
264
265 data = (Ipp8u*)XMALLOC(length, NULL, DYNAMIC_TYPE_USER_CRYPTO);
266 if (data == NULL)
267 return USER_CRYPTO_ERROR;
268
269 /* extract the wolfSSL BigNum and store it into IPP BigNum */
270 if (wolfSSL_BN_bn2bin(bn, data) < 0) {
271 XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
272 USER_DEBUG(("error in getting bin from wolfssl bn\n"));
273 return USER_CRYPTO_ERROR;
274 }
275
276 ret = ippsSetOctString_BN(data, length, *mpi);
277 if (ret != ippStsNoErr) {
278 XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
279 return USER_CRYPTO_ERROR;
280 }
281
282 XFREE(data, NULL, DYNAMIC_TYPE_USER_CRYPTO);
283
284 return 0;
285 }
286
287
288 /* WolfSSL -> OpenSSL */
SetRsaExternal(WOLFSSL_RSA * rsa)289 int SetRsaExternal(WOLFSSL_RSA* rsa)
290 {
291 RsaKey* key;
292 USER_DEBUG(("Entering SetRsaExternal\n"));
293
294 if (rsa == NULL || rsa->internal == NULL) {
295 USER_DEBUG(("rsa key NULL error\n"));
296 return USER_CRYPTO_ERROR;
297 }
298
299 key = (RsaKey*)rsa->internal;
300
301 if (SetIndividualExternal(&rsa->n, key->n) != 0) {
302 USER_DEBUG(("rsa n key error\n"));
303 return USER_CRYPTO_ERROR;
304 }
305
306 if (SetIndividualExternal(&rsa->e, key->e) != 0) {
307 USER_DEBUG(("rsa e key error\n"));
308 return USER_CRYPTO_ERROR;
309 }
310
311 if (key->type == RSA_PRIVATE) {
312 if (SetIndividualExternal(&rsa->d, key->dipp) != 0) {
313 USER_DEBUG(("rsa d key error\n"));
314 return USER_CRYPTO_ERROR;
315 }
316
317 if (SetIndividualExternal(&rsa->p, key->pipp) != 0) {
318 USER_DEBUG(("rsa p key error\n"));
319 return USER_CRYPTO_ERROR;
320 }
321
322 if (SetIndividualExternal(&rsa->q, key->qipp) != 0) {
323 USER_DEBUG(("rsa q key error\n"));
324 return USER_CRYPTO_ERROR;
325 }
326
327 if (SetIndividualExternal(&rsa->dmp1, key->dPipp) != 0) {
328 USER_DEBUG(("rsa dP key error\n"));
329 return USER_CRYPTO_ERROR;
330 }
331
332 if (SetIndividualExternal(&rsa->dmq1, key->dQipp) != 0) {
333 USER_DEBUG(("rsa dQ key error\n"));
334 return USER_CRYPTO_ERROR;
335 }
336
337 if (SetIndividualExternal(&rsa->iqmp, key->uipp) != 0) {
338 USER_DEBUG(("rsa u key error\n"));
339 return USER_CRYPTO_ERROR;
340 }
341 }
342
343 rsa->exSet = 1;
344
345 /* SSL_SUCCESS */
346 return 1;
347 }
348
349
350 /* Openssl -> WolfSSL */
SetRsaInternal(WOLFSSL_RSA * rsa)351 int SetRsaInternal(WOLFSSL_RSA* rsa)
352 {
353 int ctxSz, pSz, qSz;
354 IppStatus ret;
355 RsaKey* key;
356 USER_DEBUG(("Entering SetRsaInternal\n"));
357
358 if (rsa == NULL || rsa->internal == NULL) {
359 USER_DEBUG(("rsa key NULL error\n"));
360 return USER_CRYPTO_ERROR;
361 }
362
363 key = (RsaKey*)rsa->internal;
364
365 if (SetIndividualInternal(rsa->n, &key->n) != 0) {
366 USER_DEBUG(("rsa n key error\n"));
367 return USER_CRYPTO_ERROR;
368 }
369
370 if (SetIndividualInternal(rsa->e, &key->e) != 0) {
371 USER_DEBUG(("rsa e key error\n"));
372 return USER_CRYPTO_ERROR;
373 }
374
375 /* public key */
376 key->type = RSA_PUBLIC;
377
378 if (rsa->d != NULL) {
379 if (SetIndividualInternal(rsa->d, &key->dipp) != 0) {
380 USER_DEBUG(("rsa d key error\n"));
381 return USER_CRYPTO_ERROR;
382 }
383
384 /* private key */
385 key->type = RSA_PRIVATE;
386 }
387
388 if (rsa->p != NULL &&
389 SetIndividualInternal(rsa->p, &key->pipp) != 0) {
390 USER_DEBUG(("rsa p key error\n"));
391 return USER_CRYPTO_ERROR;
392 }
393
394 if (rsa->q != NULL &&
395 SetIndividualInternal(rsa->q, &key->qipp) != 0) {
396 USER_DEBUG(("rsa q key error\n"));
397 return USER_CRYPTO_ERROR;
398 }
399
400 if (rsa->dmp1 != NULL &&
401 SetIndividualInternal(rsa->dmp1, &key->dPipp) != 0) {
402 USER_DEBUG(("rsa dP key error\n"));
403 return USER_CRYPTO_ERROR;
404 }
405
406 if (rsa->dmq1 != NULL &&
407 SetIndividualInternal(rsa->dmq1, &key->dQipp) != 0) {
408 USER_DEBUG(("rsa dQ key error\n"));
409 return USER_CRYPTO_ERROR;
410 }
411
412 if (rsa->iqmp != NULL &&
413 SetIndividualInternal(rsa->iqmp, &key->uipp) != 0) {
414 USER_DEBUG(("rsa u key error\n"));
415 return USER_CRYPTO_ERROR;
416 }
417
418 rsa->inSet = 1;
419
420 /* get sizes of IPP BN key states created from input */
421 ret = ippsGetSize_BN(key->n, &key->nSz);
422 if (ret != ippStsNoErr) {
423 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
424 return USER_CRYPTO_ERROR;
425 }
426
427 ret = ippsGetSize_BN(key->e, &key->eSz);
428 if (ret != ippStsNoErr) {
429 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
430 return USER_CRYPTO_ERROR;
431 }
432
433 key->sz = key->nSz; /* set modulus size */
434
435 /* convert to size in bits */
436 key->nSz = key->nSz * 8;
437 key->eSz = key->eSz * 8;
438
439 /* set up public key state */
440 ret = ippsRSA_GetSizePublicKey(key->nSz, key->eSz, &ctxSz);
441 if (ret != ippStsNoErr) {
442 USER_DEBUG(("ippsRSA_GetSizePublicKey error %s\n",
443 ippGetStatusString(ret)));
444 return USER_CRYPTO_ERROR;
445 }
446
447 key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
448 DYNAMIC_TYPE_USER_CRYPTO);
449 if (key->pPub == NULL)
450 return USER_CRYPTO_ERROR;
451
452 ret = ippsRSA_InitPublicKey(key->nSz, key->eSz, key->pPub, ctxSz);
453 if (ret != ippStsNoErr) {
454 USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
455 ippGetStatusString(ret)));
456 return USER_CRYPTO_ERROR;
457 }
458
459 ret = ippsRSA_SetPublicKey(key->n, key->e, key->pPub);
460 if (ret != ippStsNoErr) {
461 USER_DEBUG(("ippsRSA_SetPublicKey error %s\n", ippGetStatusString(ret)));
462 return USER_CRYPTO_ERROR;
463 }
464
465 if (key->pipp != NULL && key->qipp != NULL && key->dipp != NULL &&
466 key->dPipp != NULL && key->dQipp != NULL && key->uipp != NULL) {
467 /* get bn sizes needed for private key set up */
468 ret = ippsGetSize_BN(key->pipp, &pSz);
469 if (ret != ippStsNoErr) {
470 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
471 return USER_CRYPTO_ERROR;
472 }
473
474 ret = ippsGetSize_BN(key->qipp, &qSz);
475 if (ret != ippStsNoErr) {
476 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
477 return USER_CRYPTO_ERROR;
478 }
479
480 /* store sizes needed for creating tmp private keys */
481 ret = ippsGetSize_BN(key->dipp, &key->dSz);
482 if (ret != ippStsNoErr) {
483 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
484 return USER_CRYPTO_ERROR;
485 }
486
487 /* convert to size in bits */
488 key->dSz = key->dSz * 8;
489 pSz = pSz * 8;
490 qSz = qSz * 8;
491
492 /* set up private key state */
493 ret = ippsRSA_GetSizePrivateKeyType2(pSz, qSz, &ctxSz);
494 if (ret != ippStsNoErr) {
495 USER_DEBUG(("ippsRSA_GetSizePrivateKey error %s\n",
496 ippGetStatusString(ret)));
497 return USER_CRYPTO_ERROR;
498 }
499
500 key->prvSz = ctxSz;
501 key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0,
502 DYNAMIC_TYPE_USER_CRYPTO);
503 if (key->pPrv == NULL)
504 return USER_CRYPTO_ERROR;
505
506 ret = ippsRSA_InitPrivateKeyType2(pSz, qSz, key->pPrv, ctxSz);
507 if (ret != ippStsNoErr) {
508 USER_DEBUG(("ippsRSA_InitPrivateKey error %s\n",
509 ippGetStatusString(ret)));
510 return USER_CRYPTO_ERROR;
511 }
512
513 ret = ippsRSA_SetPrivateKeyType2(key->pipp, key->qipp, key->dPipp,
514 key->dQipp, key->uipp, key->pPrv);
515 if (ret != ippStsNoErr) {
516 USER_DEBUG(("ippsRSA_SetPrivateKey error %s\n", ippGetStatusString(ret)));
517 return USER_CRYPTO_ERROR;
518 }
519 }
520
521 /* SSL_SUCCESS */
522 return 1;
523 }
524 #endif /* OPENSSLEXTRA */
525
526
527 /* Padding scheme function used in wolfSSL for signing needed for matching
528 existing API signing scheme
529 input : the msg to be signed
530 inputLen : length of input msg
531 pkcsBlock : the outputted padded msg
532 pkcsBlockLen : length of outputted padded msg buffer
533 padValue : the padded value after first 00 , is either 01 or 02
534 rng : random number generator structure
535 */
wc_RsaPad(const byte * input,word32 inputLen,byte * pkcsBlock,word32 pkcsBlockLen,byte padValue,WC_RNG * rng)536 static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
537 word32 pkcsBlockLen, byte padValue, WC_RNG* rng)
538 {
539 if (inputLen == 0 || pkcsBlockLen == 0) {
540 return USER_CRYPTO_ERROR;
541 }
542
543 pkcsBlock[0] = 0x0; /* set first byte to zero and advance */
544 pkcsBlock++; pkcsBlockLen--;
545 pkcsBlock[0] = padValue; /* insert padValue */
546
547 if (padValue == RSA_BLOCK_TYPE_1) {
548 if (pkcsBlockLen < inputLen + 2) {
549 return USER_CRYPTO_ERROR;
550 }
551
552 /* pad with 0xff bytes */
553 XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
554 }
555 else {
556 /* pad with non-zero random bytes */
557 word32 padLen, i;
558 int ret;
559
560 if (pkcsBlockLen < inputLen + 1) {
561 return USER_CRYPTO_ERROR;
562 }
563
564 padLen = pkcsBlockLen - inputLen - 1;
565 ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);
566
567 if (ret != 0)
568 return ret;
569
570 /* remove zeros */
571 for (i = 1; i < padLen; i++)
572 if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
573 }
574
575 pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */
576 XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
577
578 return 0;
579 }
580
581
582 /* UnPad plaintext, set start to *output, return length of plaintext,
583 * < 0 on error */
RsaUnPad(const byte * pkcsBlock,unsigned int pkcsBlockLen,byte ** output,byte padValue)584 static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
585 byte **output, byte padValue)
586 {
587 word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0,
588 invalid = 0,
589 i = 1,
590 outputLen;
591
592 if (pkcsBlockLen == 0) {
593 return USER_CRYPTO_ERROR;
594 }
595
596 if (pkcsBlock[0] != 0x0) /* skip past zero */
597 invalid = 1;
598 pkcsBlock++; pkcsBlockLen--;
599
600 /* Require block type padValue */
601 invalid = (pkcsBlock[0] != padValue) || invalid;
602
603 /* verify the padding until we find the separator */
604 if (padValue == RSA_BLOCK_TYPE_1) {
605 while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
606 }
607 else {
608 while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
609 }
610
611 if(!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
612 USER_DEBUG(("RsaUnPad error, bad formatting\n"));
613 return USER_CRYPTO_ERROR;
614 }
615
616 outputLen = pkcsBlockLen - i;
617 invalid = (outputLen > maxOutputLen) || invalid;
618
619 if (invalid) {
620 USER_DEBUG(("RsaUnPad error, bad formatting\n"));
621 return USER_CRYPTO_ERROR;
622 }
623
624 *output = (byte *)(pkcsBlock + i);
625 return outputLen;
626 }
627
628
629 /* Set up memory and structure for a Big Number
630 * returns ippStsNoErr on success
631 */
init_bn(IppsBigNumState ** in,int sz)632 static IppStatus init_bn(IppsBigNumState** in, int sz)
633 {
634 int ctxSz;
635 IppStatus ret;
636
637 ret = ippsBigNumGetSize(sz, &ctxSz);
638 if (ret != ippStsNoErr) {
639 return ret;
640 }
641
642 *in = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
643 if (*in == NULL) {
644 return ippStsNoMemErr;
645 }
646
647 ret = ippsBigNumInit(sz, *in);
648 if (ret != ippStsNoErr) {
649 XFREE(*in, NULL, DYNAMIC_TYPE_USER_CRYPTO);
650 *in = NULL;
651 return ret;
652 }
653
654 return ippStsNoErr;
655 }
656
657
658 /* Set up memory and structure for a Montgomery struct
659 * returns ippStsNoErr on success
660 */
init_mont(IppsMontState ** mont,int * ctxSz,IppsBigNumState * modul)661 static IppStatus init_mont(IppsMontState** mont, int* ctxSz,
662 IppsBigNumState* modul)
663 {
664 int mSz;
665 Ipp32u* m;
666 IppStatus ret;
667
668 ret = ippsExtGet_BN(NULL, ctxSz, NULL, modul);
669 if (ret != ippStsNoErr) {
670 return ret;
671 }
672
673 /* convert bits to Ipp32u array size and round up
674 32 is number of bits in type */
675 mSz = (*ctxSz/32)+((*ctxSz % 32)? 1: 0);
676 m = (Ipp32u*)XMALLOC(mSz * sizeof(Ipp32u), 0, DYNAMIC_TYPE_USER_CRYPTO);
677 if (m == NULL) {
678 XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
679 return ippStsNoMemErr;
680 }
681
682 ret = ippsExtGet_BN(NULL, NULL, m, modul);
683 if (ret != ippStsNoErr) {
684 XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
685 return ret;
686 }
687
688 ret = ippsMontGetSize(IppsSlidingWindows, mSz, ctxSz);
689 if (ret != ippStsNoErr) {
690 XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
691 return ret;
692 }
693
694 /* 2. Allocate working buffer using malloc */
695 *mont = (IppsMontState*)XMALLOC(*ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
696 if (*mont == NULL) {
697 XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
698 return ippStsNoMemErr;
699 }
700 ret = ippsMontInit(IppsSlidingWindows, mSz, *mont);
701 if (ret != ippStsNoErr) {
702 USER_DEBUG(("ippsMontInit error of %s\n", ippGetStatusString(ret)));
703 XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
704 XFREE(*mont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
705 *mont = NULL;
706 return ret;
707 }
708
709 /* 3. Call the function MontSet to set big number module */
710 ret = ippsMontSet(m, mSz, *mont);
711 if (ret != ippStsNoErr) {
712 USER_DEBUG(("ippsMontSet error of %s\n", ippGetStatusString(ret)));
713 XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
714 XFREE(*mont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
715 *mont = NULL;
716 return ret;
717 }
718
719 XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO);
720
721 return ippStsNoErr;
722 }
723
724
725
wc_FreeRsaKey(RsaKey * key)726 int wc_FreeRsaKey(RsaKey* key)
727 {
728 if (key == NULL)
729 return 0;
730
731 USER_DEBUG(("Entering wc_FreeRsaKey\n"));
732
733 if (key->pPub != NULL) {
734 XFREE(key->pPub, NULL, DYNAMIC_TYPE_USER_CRYPTO);
735 key->pPub = NULL;
736 }
737
738 if (key->pPrv != NULL) {
739 /* write over sensitive information */
740 ForceZero(key->pPrv, key->prvSz);
741 XFREE(key->pPrv, NULL, DYNAMIC_TYPE_USER_CRYPTO);
742 key->pPrv = NULL;
743 }
744
745 if (key->n != NULL) {
746 XFREE(key->n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
747 key->n = NULL;
748 }
749
750 if (key->e != NULL) {
751 XFREE(key->e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
752 key->e = NULL;
753 }
754
755 if (key->dipp != NULL) {
756 XFREE(key->dipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
757 key->dipp = NULL;
758 }
759
760 if (key->pipp != NULL) {
761 XFREE(key->pipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
762 key->pipp = NULL;
763 }
764
765 if (key->qipp != NULL) {
766 XFREE(key->qipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
767 key->qipp = NULL;
768 }
769
770 if (key->dPipp != NULL) {
771 XFREE(key->dPipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
772 key->dPipp = NULL;
773 }
774
775 if (key->dQipp != NULL) {
776 XFREE(key->dQipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
777 key->dQipp = NULL;
778 }
779
780 if (key->uipp != NULL) {
781 XFREE(key->uipp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
782 key->uipp = NULL;
783 }
784
785 USER_DEBUG(("\tExit wc_FreeRsaKey\n"));
786 (void)key;
787
788 return 0;
789 }
790
791
792 /* Some parsing functions from wolfSSL code needed to match wolfSSL API used */
GetLength(const byte * input,word32 * inOutIdx,int * len,word32 maxIdx)793 static int GetLength(const byte* input, word32* inOutIdx, int* len,
794 word32 maxIdx)
795 {
796 int length = 0;
797 word32 idx = *inOutIdx;
798 byte b;
799
800 *len = 0; /* default length */
801
802 if ((idx + 1) > maxIdx) { /* for first read */
803 USER_DEBUG(("GetLength bad index on input\n"));
804 return USER_CRYPTO_ERROR;
805 }
806
807 b = input[idx++];
808 if (b >= 0x80) {
809 word32 bytes = b & 0x7F;
810
811 if ((idx + bytes) > maxIdx) { /* for reading bytes */
812 USER_DEBUG(("GetLength bad long length\n"));
813 return USER_CRYPTO_ERROR;
814 }
815
816 while (bytes--) {
817 b = input[idx++];
818 length = (length << 8) | b;
819 }
820 }
821 else
822 length = b;
823
824 if ((idx + length) > maxIdx) { /* for user of length */
825 USER_DEBUG(("GetLength value exceeds buffer length\n"));
826 return USER_CRYPTO_ERROR;
827 }
828
829 *inOutIdx = idx;
830 if (length > 0)
831 *len = length;
832
833 return length;
834 }
835
GetASNHeader(const byte * input,byte tag,word32 * inOutIdx,int * len,word32 maxIdx)836 static int GetASNHeader(const byte* input, byte tag, word32* inOutIdx, int* len,
837 word32 maxIdx)
838 {
839 word32 idx = *inOutIdx;
840 byte b;
841 int length;
842
843 if ((idx + 1) > maxIdx)
844 return USER_CRYPTO_ERROR;
845
846 b = input[idx++];
847 if (b != tag)
848 return USER_CRYPTO_ERROR;
849
850 if (GetLength(input, &idx, &length, maxIdx) < 0)
851 return USER_CRYPTO_ERROR;
852
853 *len = length;
854 *inOutIdx = idx;
855 return length;
856 }
857
GetASNInt(const byte * input,word32 * inOutIdx,int * len,word32 maxIdx)858 static int GetASNInt(const byte* input, word32* inOutIdx, int* len,
859 word32 maxIdx)
860 {
861 int ret;
862
863 ret = GetASNHeader(input, ASN_INTEGER, inOutIdx, len, maxIdx);
864 if (ret < 0)
865 return ret;
866
867 if (*len > 0) {
868 /* remove leading zero, unless there is only one 0x00 byte */
869 if ((input[*inOutIdx] == 0x00) && (*len > 1)) {
870 (*inOutIdx)++;
871 (*len)--;
872
873 if (*len > 0 && (input[*inOutIdx] & 0x80) == 0)
874 return USER_CRYPTO_ERROR;
875 }
876 }
877
878 return 0;
879 }
880
GetInt(IppsBigNumState ** mpi,const byte * input,word32 * inOutIdx,word32 maxIdx)881 static int GetInt(IppsBigNumState** mpi, const byte* input, word32* inOutIdx,
882 word32 maxIdx)
883 {
884 IppStatus ret;
885 word32 idx = *inOutIdx;
886 int length;
887 int ctxSz;
888
889 if (GetASNInt(input, &idx, &length, maxIdx) < 0) {
890 return USER_CRYPTO_ERROR;
891 }
892
893 ret = ippsBigNumGetSize(length, &ctxSz);
894 if (ret != ippStsNoErr)
895 return USER_CRYPTO_ERROR;
896
897 *mpi = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
898 if (*mpi == NULL)
899 return USER_CRYPTO_ERROR;
900
901 ret = ippsBigNumInit(length, *mpi);
902 if (ret != ippStsNoErr)
903 return USER_CRYPTO_ERROR;
904
905 ret = ippsSetOctString_BN((Ipp8u*)input + idx, length, *mpi);
906 if (ret != ippStsNoErr)
907 return USER_CRYPTO_ERROR;
908
909 *inOutIdx = idx + length;
910 return 0;
911 }
912
913
GetSequence(const byte * input,word32 * inOutIdx,int * len,word32 maxIdx)914 static int GetSequence(const byte* input, word32* inOutIdx, int* len,
915 word32 maxIdx)
916 {
917 int length = -1;
918 word32 idx = *inOutIdx;
919
920 if ((idx + 1) > maxIdx)
921 return USER_CRYPTO_ERROR;
922
923 if (input[idx++] != (0x10 | 0x20) ||
924 GetLength(input, &idx, &length, maxIdx) < 0)
925 return USER_CRYPTO_ERROR;
926
927 *len = length;
928 *inOutIdx = idx;
929
930 return length;
931 }
932
933
GetMyVersion(const byte * input,word32 * inOutIdx,int * version,word32 maxIdx)934 static int GetMyVersion(const byte* input, word32* inOutIdx,
935 int* version, word32 maxIdx)
936 {
937 word32 idx = *inOutIdx;
938
939 if ((idx + 3) > maxIdx)
940 return USER_CRYPTO_ERROR;
941
942 if (input[idx++] != 0x02)
943 return USER_CRYPTO_ERROR;
944
945 if (input[idx++] != 0x01)
946 return USER_CRYPTO_ERROR;
947
948 *version = input[idx++];
949 *inOutIdx = idx;
950
951 return *version;
952 }
953
954
wc_RsaPrivateKeyDecode(const byte * input,word32 * inOutIdx,RsaKey * key,word32 inSz)955 int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
956 word32 inSz)
957 {
958 int version, length;
959 int ctxSz, pSz, qSz;
960 IppStatus ret;
961
962 if (input == NULL || inOutIdx == NULL || key == NULL) {
963 return USER_CRYPTO_ERROR;
964 }
965
966 USER_DEBUG(("Entering wc_RsaPrivateKeyDecode\n"));
967
968 /* read in key information */
969 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
970 return USER_CRYPTO_ERROR;
971
972 if (GetMyVersion(input, inOutIdx, &version, inSz) < 0)
973 return USER_CRYPTO_ERROR;
974
975 key->type = RSA_PRIVATE;
976
977 if (GetInt(&key->n, input, inOutIdx, inSz) < 0 ||
978 GetInt(&key->e, input, inOutIdx, inSz) < 0 ||
979 GetInt(&key->dipp, input, inOutIdx, inSz) < 0 ||
980 GetInt(&key->pipp, input, inOutIdx, inSz) < 0 ||
981 GetInt(&key->qipp, input, inOutIdx, inSz) < 0 ||
982 GetInt(&key->dPipp, input, inOutIdx, inSz) < 0 ||
983 GetInt(&key->dQipp, input, inOutIdx, inSz) < 0 ||
984 GetInt(&key->uipp, input, inOutIdx, inSz) < 0 )
985 return USER_CRYPTO_ERROR;
986
987 /* get sizes of IPP BN key states created from input */
988 ret = ippsGetSize_BN(key->n, &key->nSz);
989 if (ret != ippStsNoErr) {
990 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
991 return USER_CRYPTO_ERROR;
992 }
993
994 ret = ippsGetSize_BN(key->e, &key->eSz);
995 if (ret != ippStsNoErr) {
996 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
997 return USER_CRYPTO_ERROR;
998 }
999
1000 key->sz = key->nSz; /* set modulus size */
1001
1002 /* convert to size in bits */
1003 key->nSz = key->nSz * 8;
1004 key->eSz = key->eSz * 8;
1005
1006 /* set up public key state */
1007 ret = ippsRSA_GetSizePublicKey(key->nSz, key->eSz, &ctxSz);
1008 if (ret != ippStsNoErr) {
1009 USER_DEBUG(("ippsRSA_GetSizePublicKey error %s\n",
1010 ippGetStatusString(ret)));
1011 return USER_CRYPTO_ERROR;
1012 }
1013
1014 key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
1015 DYNAMIC_TYPE_USER_CRYPTO);
1016 if (key->pPub == NULL)
1017 return USER_CRYPTO_ERROR;
1018
1019 ret = ippsRSA_InitPublicKey(key->nSz, key->eSz, key->pPub, ctxSz);
1020 if (ret != ippStsNoErr) {
1021 USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
1022 ippGetStatusString(ret)));
1023 return USER_CRYPTO_ERROR;
1024 }
1025
1026 ret = ippsRSA_SetPublicKey(key->n, key->e, key->pPub);
1027 if (ret != ippStsNoErr) {
1028 USER_DEBUG(("ippsRSA_SetPublicKey error %s\n",
1029 ippGetStatusString(ret)));
1030 return USER_CRYPTO_ERROR;
1031 }
1032
1033 /* get bn sizes needed for private key set up */
1034 ret = ippsGetSize_BN(key->pipp, &pSz);
1035 if (ret != ippStsNoErr) {
1036 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
1037 return USER_CRYPTO_ERROR;
1038 }
1039
1040 ret = ippsGetSize_BN(key->qipp, &qSz);
1041 if (ret != ippStsNoErr) {
1042 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
1043 return USER_CRYPTO_ERROR;
1044 }
1045
1046 /* store sizes needed for creating tmp private keys */
1047 ret = ippsGetSize_BN(key->dipp, &key->dSz);
1048 if (ret != ippStsNoErr) {
1049 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
1050 return USER_CRYPTO_ERROR;
1051 }
1052
1053 /* convert to size in bits */
1054 key->dSz = key->dSz * 8;
1055 pSz = pSz * 8;
1056 qSz = qSz * 8;
1057
1058 /* set up private key state */
1059 ret = ippsRSA_GetSizePrivateKeyType2(pSz, qSz, &ctxSz);
1060 if (ret != ippStsNoErr) {
1061 USER_DEBUG(("ippsRSA_GetSizePrivateKey error %s\n",
1062 ippGetStatusString(ret)));
1063 return USER_CRYPTO_ERROR;
1064 }
1065
1066 key->prvSz = ctxSz;
1067 key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0,
1068 DYNAMIC_TYPE_USER_CRYPTO);
1069 if (key->pPrv == NULL)
1070 return USER_CRYPTO_ERROR;
1071
1072 ret = ippsRSA_InitPrivateKeyType2(pSz, qSz, key->pPrv, ctxSz);
1073 if (ret != ippStsNoErr) {
1074 USER_DEBUG(("ippsRSA_InitPrivateKey error %s\n",
1075 ippGetStatusString(ret)));
1076 return USER_CRYPTO_ERROR;
1077 }
1078
1079 ret = ippsRSA_SetPrivateKeyType2(key->pipp, key->qipp, key->dPipp,
1080 key->dQipp, key->uipp, key->pPrv);
1081 if (ret != ippStsNoErr) {
1082 USER_DEBUG(("ippsRSA_SetPrivateKey error %s\n",
1083 ippGetStatusString(ret)));
1084 return USER_CRYPTO_ERROR;
1085 }
1086
1087 USER_DEBUG(("\tExit wc_RsaPrivateKeyDecode\n"));
1088
1089 return 0;
1090 }
1091
1092
wc_RsaPublicKeyDecode_ex(const byte * input,word32 * inOutIdx,word32 inSz,const byte ** n,word32 * nSz,const byte ** e,word32 * eSz)1093 int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx,
1094 word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz)
1095 {
1096 IppStatus ret = 0;
1097 int length;
1098 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
1099 byte b;
1100 #endif
1101
1102 if (input == NULL || inOutIdx == NULL) {
1103 return USER_CRYPTO_ERROR;
1104 }
1105
1106 USER_DEBUG(("Entering wc_RsaPublicKeyDecode_ex\n"));
1107
1108 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1109 return USER_CRYPTO_ERROR;
1110
1111 #if defined(OPENSSL_EXTRA) || defined(RSA_DECODE_EXTRA)
1112 if ((*inOutIdx + 1) > inSz)
1113 return USER_CRYPTO_ERROR;
1114
1115 b = input[*inOutIdx];
1116 if (b != ASN_INTEGER) {
1117 /* not from decoded cert, will have algo id, skip past */
1118 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1119 return USER_CRYPTO_ERROR;
1120
1121 b = input[(*inOutIdx)++];
1122 if (b != ASN_OBJECT_ID)
1123 return USER_CRYPTO_ERROR;
1124
1125 if (GetLength(input, inOutIdx, &length, inSz) < 0)
1126 return USER_CRYPTO_ERROR;
1127
1128 *inOutIdx += length; /* skip past */
1129
1130 /* could have NULL tag and 0 terminator, but may not */
1131 b = input[(*inOutIdx)++];
1132
1133 if (b == ASN_TAG_NULL) {
1134 b = input[(*inOutIdx)++];
1135 if (b != 0)
1136 return USER_CRYPTO_ERROR;
1137 }
1138 else {
1139 /* go back, didn't have it */
1140 (*inOutIdx)--;
1141 }
1142
1143 /* should have bit tag length and seq next */
1144 b = input[(*inOutIdx)++];
1145 if (b != ASN_BIT_STRING)
1146 return USER_CRYPTO_ERROR;
1147
1148 if (GetLength(input, inOutIdx, &length, inSz) <= 0)
1149 return USER_CRYPTO_ERROR;
1150
1151 /* could have 0 */
1152 b = input[(*inOutIdx)++];
1153 if (b != 0)
1154 (*inOutIdx)--;
1155
1156 if (GetSequence(input, inOutIdx, &length, inSz) < 0)
1157 return USER_CRYPTO_ERROR;
1158 }
1159 #endif /* OPENSSL_EXTRA || RSA_DECODE_EXTRA */
1160
1161 /* Get modulus */
1162 ret = GetASNInt(input, inOutIdx, &length, inSz);
1163 if (ret < 0) {
1164 return USER_CRYPTO_ERROR;
1165 }
1166 if (nSz)
1167 *nSz = length;
1168 if (n)
1169 *n = &input[*inOutIdx];
1170 *inOutIdx += length;
1171
1172 /* Get exponent */
1173 ret = GetASNInt(input, inOutIdx, &length, inSz);
1174 if (ret < 0) {
1175 return USER_CRYPTO_ERROR;
1176 }
1177 if (eSz)
1178 *eSz = length;
1179 if (e)
1180 *e = &input[*inOutIdx];
1181 *inOutIdx += length;
1182
1183 USER_DEBUG(("\tExit wc_RsaPublicKeyDecode_ex\n"));
1184
1185 return ret;
1186 }
1187
1188 /* read in a public RSA key */
wc_RsaPublicKeyDecode(const byte * input,word32 * inOutIdx,RsaKey * key,word32 inSz)1189 int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
1190 word32 inSz)
1191 {
1192 IppStatus ret;
1193 const byte *n = NULL, *e = NULL;
1194 word32 nSz = 0, eSz = 0;
1195
1196 if (key == NULL)
1197 return USER_CRYPTO_ERROR;
1198
1199 USER_DEBUG(("Entering wc_RsaPublicKeyDecode\n"));
1200
1201 ret = wc_RsaPublicKeyDecode_ex(input, inOutIdx, inSz, &n, &nSz, &e, &eSz);
1202 if (ret == 0) {
1203 ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key);
1204 }
1205
1206 USER_DEBUG(("\tExit RsaPublicKeyDecode\n"));
1207
1208 return ret;
1209 }
1210
1211 /* import RSA public key elements (n, e) into RsaKey structure (key) */
wc_RsaPublicKeyDecodeRaw(const byte * n,word32 nSz,const byte * e,word32 eSz,RsaKey * key)1212 int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
1213 word32 eSz, RsaKey* key)
1214 {
1215 IppStatus ret;
1216 int ctxSz;
1217
1218 USER_DEBUG(("Entering wc_RsaPublicKeyDecodeRaw\n"));
1219
1220 if (n == NULL || e == NULL || key == NULL)
1221 return USER_CRYPTO_ERROR;
1222
1223 /* set up IPP key states -- read in n */
1224 ret = init_bn(&key->n, nSz);
1225 if (ret != ippStsNoErr)
1226 return USER_CRYPTO_ERROR;
1227
1228 ret = ippsSetOctString_BN((Ipp8u*)n, nSz, key->n);
1229 if (ret != ippStsNoErr)
1230 return USER_CRYPTO_ERROR;
1231
1232 /* read in e */
1233 ret = init_bn(&key->e, eSz);
1234 if (ret != ippStsNoErr)
1235 return USER_CRYPTO_ERROR;
1236
1237 ret = ippsSetOctString_BN((Ipp8u*)e, eSz, key->e);
1238 if (ret != ippStsNoErr)
1239 return USER_CRYPTO_ERROR;
1240
1241 /* store size and convert to binary */
1242 key->sz = nSz;
1243 nSz = nSz * 8;
1244 eSz = eSz * 8;
1245
1246 /* set up public key state */
1247 ret = ippsRSA_GetSizePublicKey(nSz, eSz, &ctxSz);
1248 if (ret != ippStsNoErr) {
1249 USER_DEBUG(("ippsRSA_GetSizePublicKey error %s\n",
1250 ippGetStatusString(ret)));
1251 return USER_CRYPTO_ERROR;
1252 }
1253
1254 key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
1255 DYNAMIC_TYPE_USER_CRYPTO);
1256 if (key->pPub == NULL)
1257 return USER_CRYPTO_ERROR;
1258
1259 ret = ippsRSA_InitPublicKey(nSz, eSz, key->pPub, ctxSz);
1260 if (ret != ippStsNoErr) {
1261 USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
1262 ippGetStatusString(ret)));
1263 return USER_CRYPTO_ERROR;
1264 }
1265
1266 ret = ippsRSA_SetPublicKey(key->n,key->e, key->pPub);
1267 if (ret != ippStsNoErr) {
1268 USER_DEBUG(("ippsRSA_SetPublicKey error %s\n",
1269 ippGetStatusString(ret)));
1270 return USER_CRYPTO_ERROR;
1271 }
1272
1273 key->nSz = nSz;
1274 key->eSz = eSz;
1275 key->type = RSA_PUBLIC;
1276
1277 return 0;
1278 }
1279
1280
1281 /* encrypt using PKCS v15 */
wc_RsaPublicEncrypt(const byte * in,word32 inLen,byte * out,word32 outLen,RsaKey * key,WC_RNG * rng)1282 int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
1283 RsaKey* key, WC_RNG* rng)
1284 {
1285 IppStatus ret;
1286 Ipp8u* scratchBuffer;
1287 int scratchSz;
1288
1289 if (key == NULL || in == NULL || out == NULL)
1290 return USER_CRYPTO_ERROR;
1291
1292 if (key->pPub == NULL || outLen < key->sz)
1293 return USER_CRYPTO_ERROR;
1294
1295 /* set size of scratch buffer */
1296 ret = ippsRSA_GetBufferSizePublicKey(&scratchSz, key->pPub);
1297 if (ret != ippStsNoErr)
1298 return USER_CRYPTO_ERROR;
1299
1300 scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0,
1301 DYNAMIC_TYPE_USER_CRYPTO);
1302 if (scratchBuffer == NULL)
1303 return USER_CRYPTO_ERROR;
1304
1305 ret = ippsRSAEncrypt_PKCSv15((Ipp8u*)in, inLen, NULL, (Ipp8u*)out,
1306 key->pPub, scratchBuffer);
1307 if (ret != ippStsNoErr) {
1308 XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1309 USER_DEBUG(("encrypt error of %s\n", ippGetStatusString(ret)));
1310 return USER_CRYPTO_ERROR;
1311 }
1312
1313 XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1314
1315 (void)rng;
1316 return key->sz;
1317 }
1318
1319
1320 /* decrypt using PLCS v15 */
wc_RsaPrivateDecrypt(const byte * in,word32 inLen,byte * out,word32 outLen,RsaKey * key)1321 int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
1322 RsaKey* key)
1323 {
1324 IppStatus ret;
1325 Ipp8u* scratchBuffer;
1326 int scratchSz;
1327 int outSz;
1328
1329 if (in == NULL || out == NULL || key == NULL)
1330 return USER_CRYPTO_ERROR;
1331
1332 if (key->pPrv == NULL || inLen != key->sz)
1333 return USER_CRYPTO_ERROR;
1334
1335 outSz = outLen;
1336
1337 /* set size of scratch buffer */
1338 ret = ippsRSA_GetBufferSizePrivateKey(&scratchSz, key->pPrv);
1339 if (ret != ippStsNoErr) {
1340 return USER_CRYPTO_ERROR;
1341 }
1342
1343 scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0,
1344 DYNAMIC_TYPE_USER_CRYPTO);
1345 if (scratchBuffer == NULL) {
1346 return USER_CRYPTO_ERROR;
1347 }
1348
1349 /* perform decryption using IPP */
1350 ret = ippsRSADecrypt_PKCSv15((Ipp8u*)in, (Ipp8u*)out, &outSz, key->pPrv,
1351 scratchBuffer);
1352 if (ret != ippStsNoErr) {
1353 XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1354 USER_DEBUG(("decrypt error of %s\n", ippGetStatusString(ret)));
1355 return USER_CRYPTO_ERROR;
1356 }
1357
1358 XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1359
1360 return outSz;
1361 }
1362
1363
1364 /* out is a pointer that is set to the location in byte array "in" where input
1365 data has been decrypted */
wc_RsaPrivateDecryptInline(byte * in,word32 inLen,byte ** out,RsaKey * key)1366 int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
1367 {
1368 int outSz;
1369 byte* tmp;
1370
1371 USER_DEBUG(("Entering wc_RsaPrivateDecryptInline\n"));
1372
1373 /* allocate a buffer for max decrypted text */
1374 tmp = (byte*)XMALLOC(key->sz, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1375 if (tmp == NULL)
1376 return USER_CRYPTO_ERROR;
1377
1378 outSz = wc_RsaPrivateDecrypt(in, inLen, tmp, key->sz, key);
1379 if (outSz >= 0) {
1380 XMEMCPY(in, tmp, outSz);
1381 *out = in;
1382 }
1383 else {
1384 XFREE(tmp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1385 return USER_CRYPTO_ERROR;
1386 }
1387
1388 XFREE(tmp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1389 USER_DEBUG(("\tExit wc_RsaPrivateDecryptInline\n"));
1390
1391 return outSz;
1392 }
1393
1394
1395 /* Used to clean up memory when exiting, clean up memory used */
FreeHelper(IppsBigNumState * pTxt,IppsBigNumState * cTxt,Ipp8u * scratchBuffer,void * pPub)1396 static int FreeHelper(IppsBigNumState* pTxt, IppsBigNumState* cTxt,
1397 Ipp8u* scratchBuffer, void* pPub)
1398 {
1399 if (pTxt != NULL)
1400 XFREE(pTxt, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1401 if (cTxt != NULL)
1402 XFREE(cTxt, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1403 if (scratchBuffer != NULL)
1404 XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1405 if (pPub != NULL)
1406 XFREE(pPub, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1407
1408 return 0;
1409 }
1410
1411
1412 /* for Rsa Verify
1413 in : byte array to be verified
1414 inLen : length of input array
1415 out : pointer to location of in byte array that has been verified
1416 */
wc_RsaSSL_VerifyInline(byte * in,word32 inLen,byte ** out,RsaKey * key)1417 int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
1418 {
1419
1420 int ctxSz;
1421 int scratchSz;
1422 Ipp8u* scratchBuffer = NULL;
1423 IppStatus ret;
1424 IppsRSAPrivateKeyState* pPub = NULL;
1425 IppsBigNumState* pTxt = NULL;
1426 IppsBigNumState* cTxt = NULL;
1427
1428 USER_DEBUG(("Entering wc_RsaSSL_VerifyInline\n"));
1429
1430 if (key == NULL || key->n == NULL || key->e == NULL) {
1431 USER_DEBUG(("n or e element was null\n"));
1432 return USER_CRYPTO_ERROR;
1433 }
1434
1435 if (in == NULL || inLen == 0 || out == NULL)
1436 return USER_CRYPTO_ERROR;
1437
1438 /* set up a private key state using public key values */
1439 ret = ippsRSA_GetSizePrivateKeyType1(key->nSz, key->eSz, &ctxSz);
1440 if (ret != ippStsNoErr) {
1441 USER_DEBUG(("ippsRSA_GetSizePrivateKey error %s\n",
1442 ippGetStatusString(ret)));
1443 return USER_CRYPTO_ERROR;
1444 }
1445
1446 pPub = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
1447 if (pPub == NULL)
1448 return USER_CRYPTO_ERROR;
1449
1450 ret = ippsRSA_InitPrivateKeyType1(key->nSz, key->eSz, pPub, ctxSz);
1451 if (ret != ippStsNoErr) {
1452 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1453 USER_DEBUG(("ippsRSA_InitPrivateKey error %s\n",
1454 ippGetStatusString(ret)));
1455 return USER_CRYPTO_ERROR;
1456 }
1457
1458 ret = ippsRSA_SetPrivateKeyType1(key->n, key->e, pPub);
1459 if (ret != ippStsNoErr) {
1460 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1461 USER_DEBUG(("ippsRSA_SetPrivateKey error %s\n",
1462 ippGetStatusString(ret)));
1463 return USER_CRYPTO_ERROR;
1464 }
1465
1466 /* set size of scratch buffer */
1467 ret = ippsRSA_GetBufferSizePrivateKey(&scratchSz, pPub);
1468 if (ret != ippStsNoErr) {
1469 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1470 return USER_CRYPTO_ERROR;
1471 }
1472
1473 scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0,
1474 DYNAMIC_TYPE_USER_CRYPTO);
1475 if (scratchBuffer == NULL) {
1476 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1477 return USER_CRYPTO_ERROR;
1478 }
1479
1480 /* load plain and cipher into big num states */
1481 ret = init_bn(&pTxt, key->sz);
1482 if (ret != ippStsNoErr) {
1483 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1484 return USER_CRYPTO_ERROR;
1485 }
1486 ret = ippsSetOctString_BN((Ipp8u*)in, key->sz, pTxt);
1487 if (ret != ippStsNoErr) {
1488 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1489 return USER_CRYPTO_ERROR;
1490 }
1491
1492 /* set up cipher to hold signature */
1493 ret = init_bn(&cTxt, key->sz);
1494 if (ret != ippStsNoErr) {
1495 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1496 return USER_CRYPTO_ERROR;
1497 }
1498 ret = ippsSetOctString_BN((Ipp8u*)in, key->sz, cTxt);
1499 if (ret != ippStsNoErr) {
1500 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1501 return USER_CRYPTO_ERROR;
1502 }
1503
1504 /* decrypt using public key information */
1505 ret = ippsRSA_Decrypt(cTxt, pTxt, pPub, scratchBuffer);
1506 if (ret != ippStsNoErr) {
1507 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1508 USER_DEBUG(("decrypt error of %s\n", ippGetStatusString(ret)));
1509 return USER_CRYPTO_ERROR;
1510 }
1511
1512 /* extract big num struct to octet string */
1513 ret = ippsGetOctString_BN((Ipp8u*)in, key->sz, pTxt);
1514 if (ret != ippStsNoErr) {
1515 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1516 USER_DEBUG(("BN get string error of %s\n", ippGetStatusString(ret)));
1517 return USER_CRYPTO_ERROR;
1518 }
1519
1520 FreeHelper(pTxt, cTxt, scratchBuffer, pPub);
1521
1522 /* unpad the decrypted information and return size of array */
1523 return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1);
1524 }
1525
1526
1527 /* sets up and call VerifyInline to verify a signature */
wc_RsaSSL_Verify(const byte * in,word32 inLen,byte * out,word32 outLen,RsaKey * key)1528 int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
1529 RsaKey* key)
1530 {
1531 int plainLen;
1532 byte* tmp;
1533 byte* pad = 0;
1534
1535 if (out == NULL || in == NULL || key == NULL)
1536 return USER_CRYPTO_ERROR;
1537
1538 tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_USER_CRYPTO);
1539 if (tmp == NULL) {
1540 return USER_CRYPTO_ERROR;
1541 }
1542
1543 XMEMCPY(tmp, in, inLen);
1544
1545 /* verify signature and test if output buffer is large enough */
1546 plainLen = wc_RsaSSL_VerifyInline(tmp, inLen, &pad, key);
1547 if (plainLen < 0) {
1548 XFREE(tmp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1549 return plainLen;
1550 }
1551
1552 if (plainLen > (int)outLen)
1553 plainLen = USER_CRYPTO_ERROR;
1554 else
1555 XMEMCPY(out, pad, plainLen);
1556
1557 ForceZero(tmp, inLen);
1558 XFREE(tmp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1559
1560 return plainLen;
1561 }
1562
1563
1564 /* Check if a > b , if so c = a mod b
1565 return ippStsNoErr on success */
reduce(IppsBigNumState * a,IppsBigNumState * b,IppsBigNumState * c)1566 static IppStatus reduce(IppsBigNumState* a, IppsBigNumState* b,
1567 IppsBigNumState* c)
1568 {
1569 IppStatus ret;
1570
1571 if ((ret = ippsMod_BN(a, b, c)) != ippStsNoErr)
1572 return ret;
1573
1574 return ippStsNoErr;
1575 }
1576
1577
exptmod(IppsBigNumState * a,IppsBigNumState * b,IppsMontState * mont,IppsBigNumState * out,IppsBigNumState * one)1578 static IppStatus exptmod(IppsBigNumState* a, IppsBigNumState* b,
1579 IppsMontState* mont, IppsBigNumState* out, IppsBigNumState* one)
1580 {
1581 IppStatus ret;
1582
1583 ret = ippsMontForm(a, mont, a);
1584 if (ret != ippStsNoErr) {
1585 USER_DEBUG(("ippsMontForm error of %s\n", ippGetStatusString(ret)));
1586 return ret;
1587 }
1588
1589 /* a = a^b mod mont */
1590 ret = ippsMontExp(a, b, mont, out);
1591 if (ret != ippStsNoErr) {
1592 USER_DEBUG(("ippsMontExp error of %s\n", ippGetStatusString(ret)));
1593 return ret;
1594 }
1595
1596 /* convert back from montgomery */
1597 ret = ippsMontMul(out, one, mont, out);
1598 if (ret != ippStsNoErr) {
1599 USER_DEBUG(("ippsMontMul error of %s\n", ippGetStatusString(ret)));
1600 return ret;
1601 }
1602
1603 return ippStsNoErr;
1604 }
1605
1606
Free_BN(IppsBigNumState * bn)1607 static void Free_BN(IppsBigNumState* bn)
1608 {
1609 int sz, ctxSz;
1610 IppStatus ret;
1611
1612 if (bn != NULL) {
1613 ret = ippStsNoErr;
1614 ret |= ippsGetSize_BN(bn, &sz);
1615 ret |= ippsBigNumGetSize(sz, &ctxSz);
1616 if (ret == ippStsNoErr) {
1617 ForceZero(bn, ctxSz);
1618 }
1619 else {
1620 USER_DEBUG(("Issue with clearing a struct in RsaSSL_Sign free\n"));
1621 }
1622 XFREE(bn, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1623 }
1624 }
1625
1626
1627 /* free up memory used during CRT sign operation */
FreeSignHelper(IppsBigNumState * one,IppsBigNumState * tmp,IppsBigNumState * tmpP,IppsBigNumState * tmpQ,IppsBigNumState * tmpa,IppsBigNumState * tmpb)1628 static void FreeSignHelper(IppsBigNumState* one, IppsBigNumState* tmp,
1629 IppsBigNumState* tmpP, IppsBigNumState* tmpQ, IppsBigNumState* tmpa,
1630 IppsBigNumState* tmpb)
1631 {
1632 Free_BN(one);
1633 Free_BN(tmp);
1634 Free_BN(tmpP);
1635 Free_BN(tmpQ);
1636 Free_BN(tmpa);
1637 Free_BN(tmpb);
1638 }
1639
1640
1641 /* for Rsa Sign */
wc_RsaSSL_Sign(const byte * in,word32 inLen,byte * out,word32 outLen,RsaKey * key,WC_RNG * rng)1642 int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
1643 RsaKey* key, WC_RNG* rng)
1644 {
1645 int sz, pSz, qSz;
1646 IppStatus ret;
1647 word32 outSz;
1648
1649 IppsMontState* pMont = NULL;
1650 IppsMontState* qMont = NULL;
1651
1652 IppsBigNumState* one = NULL;
1653 IppsBigNumState* tmp = NULL;
1654 IppsBigNumState* tmpP = NULL;
1655 IppsBigNumState* tmpQ = NULL;
1656 IppsBigNumState* tmpa = NULL;
1657 IppsBigNumState* tmpb = NULL;
1658
1659 IppsBigNumSGN sa, sb;
1660
1661 Ipp8u o[1];
1662 o[0] = 1;
1663
1664 USER_DEBUG(("Entering wc_RsaSSL_Sign\n"));
1665
1666 if (in == NULL || out == NULL || key == NULL || rng == NULL) {
1667 USER_DEBUG(("Bad argument to wc_RsaSSL_Sign\n"));
1668 return USER_CRYPTO_ERROR;
1669 }
1670
1671 sz = key->sz;
1672
1673
1674 /* sanity check on key being used */
1675 if (key->pipp == NULL || key->qipp == NULL || key->uipp == NULL ||
1676 key->dPipp == NULL || key->dQipp == NULL) {
1677 USER_DEBUG(("Bad key argument to wc_RsaSSL_Sign\n"));
1678 return USER_CRYPTO_ERROR;
1679 }
1680
1681 if (sz > (int)outLen) {
1682 USER_DEBUG(("Bad argument outLen to wc_RsaSSL_Sign\n"));
1683 return USER_CRYPTO_ERROR;
1684 }
1685
1686 if (sz < RSA_MIN_PAD_SZ) {
1687 USER_DEBUG(("Key size is too small\n"));
1688 return USER_CRYPTO_ERROR;
1689 }
1690
1691 if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) {
1692 USER_DEBUG(("Bad argument inLen to wc_RsaSSL_Sign\n"));
1693 return USER_CRYPTO_ERROR;
1694 }
1695
1696 /* Set up needed pkcs v15 padding */
1697 if (wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng) != 0) {
1698 USER_DEBUG(("RSA Padding error\n"));
1699 return USER_CRYPTO_ERROR;
1700 }
1701
1702 /* tmp = input to sign */
1703 ret = init_bn(&tmp, sz);
1704 if (ret != ippStsNoErr) {
1705 USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
1706 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1707 return USER_CRYPTO_ERROR;
1708 }
1709 ret = ippsSetOctString_BN(out, sz, tmp);
1710 if (ret != ippStsNoErr) {
1711 USER_DEBUG(("ippsSetOctString_BN error of %s\n",
1712 ippGetStatusString(ret)));
1713 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1714 return USER_CRYPTO_ERROR;
1715 }
1716
1717 /* tmpP = tmp mod p */
1718 ret = init_bn(&tmpP, sz);
1719 if (ret != ippStsNoErr) {
1720 USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
1721 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1722 return USER_CRYPTO_ERROR;
1723 }
1724
1725 /* tmpQ = tmp mod q */
1726 ret = init_bn(&tmpQ, sz);
1727 if (ret != ippStsNoErr) {
1728 USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
1729 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1730 return USER_CRYPTO_ERROR;
1731 }
1732
1733 /* tmpa */
1734 ret = init_bn(&tmpa, sz);
1735 if (ret != ippStsNoErr) {
1736 USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
1737 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1738 return USER_CRYPTO_ERROR;
1739 }
1740
1741 /* tmpb */
1742 ret = init_bn(&tmpb, sz);
1743 if (ret != ippStsNoErr) {
1744 USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
1745 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1746 return USER_CRYPTO_ERROR;
1747 }
1748
1749 /* one : used for conversion from Montgomery to classical */
1750 ret = init_bn(&one, sz);
1751 if (ret != ippStsNoErr) {
1752 USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret)));
1753 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1754 return USER_CRYPTO_ERROR;
1755 }
1756 ret = ippsSetOctString_BN(o, 1, one);
1757 if (ret != ippStsNoErr) {
1758 USER_DEBUG(("ippsSetOctString_BN error of %s\n",
1759 ippGetStatusString(ret)));
1760 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1761 return USER_CRYPTO_ERROR;
1762 }
1763
1764 /**
1765 Set up Montgomery state
1766 */
1767 ret = init_mont(&pMont, &pSz, key->pipp);
1768 if (ret != ippStsNoErr) {
1769 USER_DEBUG(("init_mont error of %s\n", ippGetStatusString(ret)));
1770 if (pMont != NULL) {
1771 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1772 }
1773 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1774 return USER_CRYPTO_ERROR;
1775 }
1776
1777 ret = init_mont(&qMont, &qSz, key->qipp);
1778 if (ret != ippStsNoErr) {
1779 USER_DEBUG(("init_mont error of %s\n", ippGetStatusString(ret)));
1780 if (qMont != NULL) {
1781 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1782 }
1783 ForceZero(pMont, pSz);
1784 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1785 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1786 return USER_CRYPTO_ERROR;
1787 }
1788
1789 /**
1790 Check and reduce input
1791 This is needed for calls to MontExp since required value of a < modulus
1792 */
1793 ret = reduce(tmp, key->pipp, tmpP);
1794 if (ret != ippStsNoErr)
1795 {
1796 USER_DEBUG(("reduce error of %s\n", ippGetStatusString(ret)));
1797 ForceZero(pMont, pSz);
1798 ForceZero(qMont, qSz);
1799 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1800 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1801 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1802 return USER_CRYPTO_ERROR;
1803 }
1804
1805 ret = reduce(tmp, key->qipp, tmpQ);
1806 if (ret != ippStsNoErr)
1807 {
1808 USER_DEBUG(("reduce error of %s\n", ippGetStatusString(ret)));
1809 ForceZero(pMont, pSz);
1810 ForceZero(qMont, qSz);
1811 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1812 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1813 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1814 return USER_CRYPTO_ERROR;
1815 }
1816
1817 /* tmpa = (tmp mod p)^dP mod p */
1818 ret = exptmod(tmpP, key->dPipp, pMont, tmpa, one);
1819 if (ret != ippStsNoErr) {
1820 USER_DEBUG(("exptmod error of %s\n", ippGetStatusString(ret)));
1821 ForceZero(pMont, pSz);
1822 ForceZero(qMont, qSz);
1823 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1824 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1825 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1826 return USER_CRYPTO_ERROR;
1827 }
1828
1829 /* tmpb = (tmp mod q)^dQ mod q */
1830 ret = exptmod(tmpQ, key->dQipp, qMont, tmpb, one);
1831 if (ret != ippStsNoErr) {
1832 USER_DEBUG(("exptmod error of %s\n", ippGetStatusString(ret)));
1833 ForceZero(pMont, pSz);
1834 ForceZero(qMont, qSz);
1835 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1836 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1837 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1838 return USER_CRYPTO_ERROR;
1839 }
1840
1841 /* tmp = (tmpa - tmpb) * qInv (mod p) */
1842 ret = ippsSub_BN(tmpa, tmpb, tmp);
1843 if (ret != ippStsNoErr) {
1844 USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret)));
1845 ForceZero(pMont, pSz);
1846 ForceZero(qMont, qSz);
1847 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1848 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1849 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1850 return USER_CRYPTO_ERROR;
1851 }
1852
1853 ret = ippsMul_BN(tmp, key->uipp, tmp);
1854 if (ret != ippStsNoErr) {
1855 USER_DEBUG(("ippsMul_BN error of %s\n", ippGetStatusString(ret)));
1856 ForceZero(pMont, pSz);
1857 ForceZero(qMont, qSz);
1858 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1859 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1860 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1861 return USER_CRYPTO_ERROR;
1862 }
1863
1864 /* mod performed the same was as wolfSSL fp_mod -- tmpa is just scratch */
1865 ret = ippsDiv_BN(tmp, key->pipp, tmpa, tmp);
1866 if (ret != ippStsNoErr) {
1867 USER_DEBUG(("ippsDiv_BN error of %s\n", ippGetStatusString(ret)));
1868 ForceZero(pMont, pSz);
1869 ForceZero(qMont, qSz);
1870 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1871 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1872 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1873 return USER_CRYPTO_ERROR;
1874 }
1875
1876 /* Check sign of values and perform conditional add */
1877 ret = ippsExtGet_BN(&sa, NULL, NULL, tmp);
1878 if (ret != ippStsNoErr) {
1879 USER_DEBUG(("ippsExtGet_BN error of %s\n", ippGetStatusString(ret)));
1880 ForceZero(pMont, pSz);
1881 ForceZero(qMont, qSz);
1882 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1883 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1884 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1885 return USER_CRYPTO_ERROR;
1886 }
1887 ret = ippsExtGet_BN(&sb, NULL, NULL, key->pipp);
1888 if (ret != ippStsNoErr) {
1889 USER_DEBUG(("ippsExtGet_BN error of %s\n", ippGetStatusString(ret)));
1890 ForceZero(pMont, pSz);
1891 ForceZero(qMont, qSz);
1892 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1893 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1894 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1895 return USER_CRYPTO_ERROR;
1896 }
1897 if (sa != sb) {
1898 ret = ippsAdd_BN(tmp, key->pipp, tmp);
1899 if (ret != ippStsNoErr) {
1900 USER_DEBUG(("ippsAdd_BN error of %s\n", ippGetStatusString(ret)));
1901 ForceZero(pMont, pSz);
1902 ForceZero(qMont, qSz);
1903 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1904 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1905 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1906 return USER_CRYPTO_ERROR;
1907 }
1908 }
1909
1910 /* tmp = tmpb + q * tmp */
1911 ret = ippsMul_BN(tmp, key->qipp, tmp);
1912 if (ret != ippStsNoErr) {
1913 USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret)));
1914 ForceZero(pMont, pSz);
1915 ForceZero(qMont, qSz);
1916 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1917 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1918 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1919 return USER_CRYPTO_ERROR;
1920 }
1921
1922
1923 ret = ippsAdd_BN(tmp, tmpb, tmp);
1924 if (ret != ippStsNoErr) {
1925 USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret)));
1926 ForceZero(pMont, pSz);
1927 ForceZero(qMont, qSz);
1928 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1929 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1930 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1931 return USER_CRYPTO_ERROR;
1932 }
1933
1934 /* Extract the output */
1935 ret = ippsGetOctString_BN(out, sz, tmp);
1936 if (ret != ippStsNoErr) {
1937 USER_DEBUG(("ippsGetOctString_BN error of %s\n",
1938 ippGetStatusString(ret)));
1939 ForceZero(pMont, pSz);
1940 ForceZero(qMont, qSz);
1941 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1942 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1943 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1944 return USER_CRYPTO_ERROR;
1945 }
1946
1947 outSz = sz;
1948
1949 /* clear memory and free */
1950 ForceZero(pMont, pSz);
1951 ForceZero(qMont, qSz);
1952 XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1953 XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO);
1954 FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb);
1955
1956 return outSz;
1957 }
1958
1959
wc_RsaEncryptSize(RsaKey * key)1960 int wc_RsaEncryptSize(RsaKey* key)
1961 {
1962 if (key == NULL)
1963 return 0;
1964
1965 return key->sz;
1966 }
1967
1968
1969 /* flatten RsaKey structure into individual elements (e, n) */
wc_RsaFlattenPublicKey(RsaKey * key,byte * e,word32 * eSz,byte * n,word32 * nSz)1970 int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,
1971 word32* nSz)
1972 {
1973 int sz, bytSz;
1974 IppStatus ret;
1975
1976 USER_DEBUG(("Entering wc_RsaFlattenPublicKey\n"));
1977
1978 if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL)
1979 return USER_CRYPTO_ERROR;
1980
1981 bytSz = sizeof(byte) * 8;
1982 ret = ippsExtGet_BN(NULL, &sz, NULL, key->e);
1983 if (ret != ippStsNoErr)
1984 return USER_CRYPTO_ERROR;
1985
1986 /* sz is in bits change to bytes */
1987 sz = (sz / bytSz) + ((sz % bytSz)? 1 : 0);
1988
1989 if (*eSz < (word32)sz)
1990 return USER_CRYPTO_ERROR;
1991
1992 ret = ippsGetOctString_BN(e, sz, key->e);
1993 if (ret != ippStsNoErr)
1994 return USER_CRYPTO_ERROR;
1995
1996 *eSz = (word32)sz;
1997
1998 /* flatten n */
1999 ret = ippsExtGet_BN(NULL, &sz, NULL, key->n);
2000 if (ret != ippStsNoErr)
2001 return USER_CRYPTO_ERROR;
2002
2003 /* sz is in bits change to bytes */
2004 sz = (sz / bytSz) + ((sz % bytSz)? 1: 0);
2005
2006 if (*nSz < (word32)sz)
2007 return USER_CRYPTO_ERROR;
2008
2009 ret = ippsGetOctString_BN(n, sz, key->n);
2010 if (ret != ippStsNoErr)
2011 return USER_CRYPTO_ERROR;
2012
2013 *nSz = (word32)sz;
2014
2015 return 0;
2016 }
2017
2018
2019 IppStatus wolfSSL_rng(Ipp32u* pData, int nBits, void* pEbsParams);
wolfSSL_rng(Ipp32u * pData,int nBits,void * pEbsParams)2020 IppStatus wolfSSL_rng(Ipp32u* pData, int nBits, void* pEbsParams)
2021 {
2022 int nBytes;
2023
2024 if (pData == NULL) {
2025 USER_DEBUG(("error with wolfSSL_rng argument\n"));
2026 return ippStsErr;
2027 }
2028
2029 nBytes = (nBits/8) + ((nBits % 8)? 1: 0);
2030 if (wc_RNG_GenerateBlock((WC_RNG*)pEbsParams, (byte*)pData, nBytes) != 0) {
2031 USER_DEBUG(("error in generating random wolfSSL block\n"));
2032 return ippStsErr;
2033 }
2034
2035 return ippStsNoErr;
2036 }
2037
2038
2039 #ifdef WOLFSSL_KEY_GEN
2040 /* Make an RSA key for size bits, with e specified, 65537 is a good e */
wc_MakeRsaKey(RsaKey * key,int size,long e,WC_RNG * rng)2041 int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
2042 {
2043 IppStatus ret;
2044 int scratchSz;
2045 int i; /* for trys on calling make key */
2046 int ctxSz;
2047
2048 IppsBigNumState* pSrcPublicExp = NULL;
2049 Ipp8u* scratchBuffer = NULL;
2050 Ipp8u eAry[8];
2051 int trys = 8; /* Miller-Rabin test parameter */
2052 IppsPrimeState* pPrime = NULL;
2053
2054 int qBitSz; /* size of q factor */
2055 int bytSz; /* size of key in bytes */
2056 int leng;
2057
2058 USER_DEBUG(("Entering wc_MakeRsaKey\n"));
2059
2060 /* get byte size and individual private key size -- round up */
2061 qBitSz = (size / 2) + ((size % 2)? 1: 0);
2062 bytSz = (size / 8) + ((size % 8)? 1: 0);
2063
2064 if (key == NULL || rng == NULL) {
2065 USER_DEBUG(("Error, NULL argument passed in\n"));
2066 return USER_CRYPTO_ERROR;
2067 }
2068
2069 if (e < 3 || (e&1) == 0)
2070 return USER_CRYPTO_ERROR;
2071
2072 if (size > RSA_MAX_SIZE || size < RSA_MIN_SIZE)
2073 return USER_CRYPTO_ERROR;
2074
2075 key->type = RSA_PRIVATE;
2076 key->sz = bytSz;
2077
2078 /* initialize prime number */
2079 ret = ippsPrimeGetSize(size, &ctxSz); /* size in bits */
2080 if (ret != ippStsNoErr) {
2081 USER_DEBUG(("ippsPrimeGetSize error of %s\n", ippGetStatusString(ret)));
2082 ret = USER_CRYPTO_ERROR;
2083 goto makeKeyEnd;
2084 }
2085
2086 pPrime = (IppsPrimeState*)XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2087 if (pPrime == NULL) {
2088 ret = USER_CRYPTO_ERROR;
2089 goto makeKeyEnd;
2090 }
2091
2092 ret = ippsPrimeInit(size, pPrime);
2093 if (ret != ippStsNoErr) {
2094 USER_DEBUG(("ippsPrimeInit error of %s\n", ippGetStatusString(ret)));
2095 ret = USER_CRYPTO_ERROR;
2096 goto makeKeyEnd;
2097 }
2098
2099 /* define RSA privete key type 2 */
2100 /* length in bits of p and q factors */
2101 ret = ippsRSA_GetSizePrivateKeyType2(qBitSz, qBitSz, &ctxSz);
2102 if (ret != ippStsNoErr) {
2103 USER_DEBUG(("ippsRSA_GetSizePrivateKeyType2 error of %s\n",
2104 ippGetStatusString(ret)));
2105 ret = USER_CRYPTO_ERROR;
2106 goto makeKeyEnd;
2107 }
2108
2109 key->prvSz = ctxSz; /* used when freeing private key */
2110 key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, NULL,
2111 DYNAMIC_TYPE_USER_CRYPTO);
2112 if (key->pPrv == NULL) {
2113 ret = USER_CRYPTO_ERROR;
2114 goto makeKeyEnd;
2115 }
2116
2117 /* length in bits of p and q factors */
2118 ret = ippsRSA_InitPrivateKeyType2(qBitSz, qBitSz, key->pPrv, ctxSz);
2119 if (ret != ippStsNoErr) {
2120 USER_DEBUG(("ippsRSA_InitPrivateKeyType2 error of %s\n",
2121 ippGetStatusString(ret)));
2122 ret = USER_CRYPTO_ERROR;
2123 goto makeKeyEnd;
2124 }
2125
2126 /* allocate scratch buffer */
2127 ret = ippsRSA_GetBufferSizePrivateKey(&scratchSz, key->pPrv);
2128 if (ret != ippStsNoErr) {
2129 USER_DEBUG(("ippsRSA_GetBufferSizePrivateKey error of %s\n",
2130 ippGetStatusString(ret)));
2131 ret = USER_CRYPTO_ERROR;
2132 goto makeKeyEnd;
2133 }
2134
2135 scratchBuffer = (Ipp8u*)XMALLOC(scratchSz, 0, DYNAMIC_TYPE_USER_CRYPTO);
2136 if (scratchBuffer == NULL) {
2137 ret = USER_CRYPTO_ERROR;
2138 goto makeKeyEnd;
2139 }
2140
2141 /* set up initial value of pScrPublicExp */
2142 leng = (int)sizeof(long); /* # of Ipp32u in long */
2143
2144 /* place the value of e into the array eAry then load into BN */
2145 for (i = 0; i < leng; i++) {
2146 eAry[i] = (e >> (8 * (leng - 1 - i))) & 0XFF;
2147 }
2148 ret = init_bn(&pSrcPublicExp, leng);
2149 if (ret != ippStsNoErr) {
2150 ret = USER_CRYPTO_ERROR;
2151 goto makeKeyEnd;
2152 }
2153
2154 ret = ippsSetOctString_BN(eAry, leng, pSrcPublicExp);
2155 if (ret != ippStsNoErr) {
2156 ret = USER_CRYPTO_ERROR;
2157 goto makeKeyEnd;
2158 }
2159
2160 /* initializing key->n */
2161 ret = init_bn(&key->n, bytSz);
2162 if (ret != ippStsNoErr) {
2163 ret = USER_CRYPTO_ERROR;
2164 goto makeKeyEnd;
2165 }
2166
2167 /* initializing public exponent key->e */
2168 ret = init_bn(&key->e, leng);
2169 if (ret != ippStsNoErr) {
2170 ret = USER_CRYPTO_ERROR;
2171 goto makeKeyEnd;
2172 }
2173
2174 /* private exponent key->dipp */
2175 ret = init_bn(&key->dipp, bytSz);
2176 if (ret != ippStsNoErr) {
2177 ret = USER_CRYPTO_ERROR;
2178 goto makeKeyEnd;
2179 }
2180
2181 /* call IPP to generate keys, if inseficent entropy error call again */
2182 ret = ippStsInsufficientEntropy;
2183 while (ret == ippStsInsufficientEntropy) {
2184 ret = ippsRSA_GenerateKeys(pSrcPublicExp, key->n, key->e,
2185 key->dipp, key->pPrv, scratchBuffer, trys, pPrime,
2186 wolfSSL_rng, rng);
2187 if (ret == ippStsNoErr) {
2188 break;
2189 }
2190
2191 /* catch all errors other than entropy error */
2192 if (ret != ippStsInsufficientEntropy) {
2193 USER_DEBUG(("ippsRSA_GeneratKeys error of %s\n",
2194 ippGetStatusString(ret)));
2195 ret = USER_CRYPTO_ERROR;
2196 goto makeKeyEnd;
2197 }
2198 }
2199
2200 /* get bn sizes needed for private key set up */
2201 ret = ippsExtGet_BN(NULL, &key->eSz, NULL, key->e);
2202 if (ret != ippStsNoErr) {
2203 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
2204 ret = USER_CRYPTO_ERROR;
2205 goto makeKeyEnd;
2206 }
2207
2208 ret = ippsExtGet_BN(NULL, &key->nSz, NULL, key->n);
2209 if (ret != ippStsNoErr) {
2210 USER_DEBUG(("ippsGetSize_BN error %s\n", ippGetStatusString(ret)));
2211 ret = USER_CRYPTO_ERROR;
2212 goto makeKeyEnd;
2213 }
2214
2215 /* set up public key state */
2216 ret = ippsRSA_GetSizePublicKey(key->nSz, key->eSz, &ctxSz);
2217 if (ret != ippStsNoErr) {
2218 USER_DEBUG(("ippsRSA_GetSizePublicKey error %s nSz = %d eSz = %d\n",
2219 ippGetStatusString(ret), key->nSz, key->eSz));
2220 ret = USER_CRYPTO_ERROR;
2221 goto makeKeyEnd;
2222 }
2223
2224 key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL,
2225 DYNAMIC_TYPE_USER_CRYPTO);
2226 if (key->pPub == NULL) {
2227 ret = USER_CRYPTO_ERROR;
2228 goto makeKeyEnd;
2229 }
2230
2231 ret = ippsRSA_InitPublicKey(key->nSz, key->eSz, key->pPub, ctxSz);
2232 if (ret != ippStsNoErr) {
2233 USER_DEBUG(("ippsRSA_InitPublicKey error %s\n",
2234 ippGetStatusString(ret)));
2235 ret = USER_CRYPTO_ERROR;
2236 goto makeKeyEnd;
2237 }
2238
2239 ret = ippsRSA_SetPublicKey(key->n, key->e, key->pPub);
2240 if (ret != ippStsNoErr) {
2241 USER_DEBUG(("ippsRSA_SetPublicKey error %s\n",
2242 ippGetStatusString(ret)));
2243 ret = USER_CRYPTO_ERROR;
2244 goto makeKeyEnd;
2245 }
2246
2247 /* get private key information for key struct */
2248 leng = size/16; /* size of q, p, u, dP, dQ */
2249 ret = init_bn(&key->pipp, leng);
2250 if (ret != ippStsNoErr) {
2251 ret = USER_CRYPTO_ERROR;
2252 goto makeKeyEnd;
2253 }
2254
2255 /* set up q BN for key */
2256 ret = init_bn(&key->qipp, leng);
2257 if (ret != ippStsNoErr) {
2258 ret = USER_CRYPTO_ERROR;
2259 goto makeKeyEnd;
2260 }
2261
2262 /* set up dP BN for key */
2263 ret = init_bn(&key->dPipp, leng);
2264 if (ret != ippStsNoErr) {
2265 ret = USER_CRYPTO_ERROR;
2266 goto makeKeyEnd;
2267 }
2268
2269 /* set up dQ BN for key */
2270 ret = init_bn(&key->dQipp, leng);
2271 if (ret != ippStsNoErr) {
2272 ret = USER_CRYPTO_ERROR;
2273 goto makeKeyEnd;
2274 }
2275
2276 /* set up u BN for key */
2277 ret = init_bn(&key->uipp, leng);
2278 if (ret != ippStsNoErr) {
2279 ret = USER_CRYPTO_ERROR;
2280 goto makeKeyEnd;
2281 }
2282
2283 /* get values from created key */
2284 ret = ippsRSA_GetPrivateKeyType2(key->pipp, key->qipp, key->dPipp,
2285 key->dQipp, key->uipp, key->pPrv);
2286 if (ret != ippStsNoErr) {
2287 USER_DEBUG(("ippsRSA_GetPrivateKeyType2 error %s\n",
2288 ippGetStatusString(ret)));
2289 ret = USER_CRYPTO_ERROR;
2290 goto makeKeyEnd;
2291 }
2292 ret = 0; /* success case */
2293
2294 makeKeyEnd:
2295 /* clean up memory used */
2296 XFREE(pSrcPublicExp, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2297 XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2298 XFREE(pPrime, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2299
2300 if (ret != 0) { /* with fail case free RSA components created */
2301 wc_FreeRsaKey(key);
2302 }
2303
2304 return ret;
2305 }
2306
2307 #endif
2308
2309 #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)
2310
2311 /********** duplicate code needed -- future refactor */
2312 #define MAX_VERSION_SZ 5
2313 #define MAX_SEQ_SZ 5
2314 #define ASN_CONTEXT_SPECIFIC 0x80
2315 #define ASN_CONSTRUCTED 0x20
2316 #define ASN_LONG_LENGTH 0x80
2317 #define ASN_SEQUENCE 0x10
2318 #define RSA_INTS 8
2319 #define FALSE 0
2320 #define TRUE 1
2321
2322 #define MAX_LENGTH_SZ 4
2323 #define RSAk 645
2324 #define keyType 2
2325 #define MAX_RSA_INT_SZ 517
2326 #define MAX_RSA_E_SZ 16
2327 #define MAX_ALGO_SZ 20
2328
BytePrecision(word32 value)2329 static word32 BytePrecision(word32 value)
2330 {
2331 word32 i;
2332 for (i = sizeof(value); i; --i)
2333 if (value >> ((i - 1) * WOLFSSL_BIT_SIZE))
2334 break;
2335
2336 return i;
2337 }
2338
2339
SetMyVersion(word32 version,byte * output,int header)2340 static int SetMyVersion(word32 version, byte* output, int header)
2341 {
2342 int i = 0;
2343
2344 if (output == NULL)
2345 return USER_CRYPTO_ERROR;
2346
2347 if (header) {
2348 output[i++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED;
2349 output[i++] = ASN_BIT_STRING;
2350 }
2351 output[i++] = ASN_INTEGER;
2352 output[i++] = 0x01;
2353 output[i++] = (byte)version;
2354
2355 return i;
2356 }
2357
2358
SetLength(word32 length,byte * output)2359 static word32 SetLength(word32 length, byte* output)
2360 {
2361 word32 i = 0, j;
2362
2363 if (length < 0x80)
2364 output[i++] = (byte)length;
2365 else {
2366 output[i++] = (byte)(BytePrecision(length) | ASN_LONG_LENGTH);
2367
2368 for (j = BytePrecision(length); j; --j) {
2369 output[i] = (byte)(length >> ((j - 1) * WOLFSSL_BIT_SIZE));
2370 i++;
2371 }
2372 }
2373
2374 return i;
2375 }
2376
2377
SetSequence(word32 len,byte * output)2378 static word32 SetSequence(word32 len, byte* output)
2379 {
2380 output[0] = ASN_SEQUENCE | ASN_CONSTRUCTED;
2381 return SetLength(len, output + 1) + 1;
2382 }
2383
2384
SetAlgoID(int algoOID,byte * output,int type,int curveSz)2385 static word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz)
2386 {
2387 /* adding TAG_NULL and 0 to end */
2388
2389 /* RSA keyType */
2390 #ifndef NO_RSA
2391 static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
2392 0x01, 0x01, 0x01, 0x05, 0x00};
2393 #endif /* NO_RSA */
2394
2395 int algoSz = 0;
2396 int tagSz = 2; /* tag null and terminator */
2397 word32 idSz, seqSz;
2398 const byte* algoName = 0;
2399 byte ID_Length[MAX_LENGTH_SZ];
2400 byte seqArray[MAX_SEQ_SZ + 1]; /* add object_id to end */
2401
2402 if (type == keyType) { /* keyType */
2403 switch (algoOID) {
2404 #ifndef NO_RSA
2405 case RSAk:
2406 algoSz = sizeof(RSA_AlgoID);
2407 algoName = RSA_AlgoID;
2408 break;
2409 #endif /* NO_RSA */
2410 default:
2411 /* unknown key algo */
2412 return 0;
2413 }
2414 }
2415 else {
2416 /* unknown algo type */
2417 return 0;
2418 }
2419
2420 idSz = SetLength(algoSz - tagSz, ID_Length); /* don't include tags */
2421 seqSz = SetSequence(idSz + algoSz + 1 + curveSz, seqArray);
2422 /* +1 for object id, curveID of curveSz follows for ecc */
2423 seqArray[seqSz++] = ASN_OBJECT_ID;
2424
2425 XMEMCPY(output, seqArray, seqSz);
2426 XMEMCPY(output + seqSz, ID_Length, idSz);
2427 XMEMCPY(output + seqSz + idSz, algoName, algoSz);
2428
2429 return seqSz + idSz + algoSz;
2430
2431 }
2432
2433
2434 /* Write a public RSA key to output */
SetRsaPublicKey(byte * output,RsaKey * key,int outLen,int with_header)2435 static int SetRsaPublicKey(byte* output, RsaKey* key,
2436 int outLen, int with_header)
2437 {
2438 #ifdef WOLFSSL_SMALL_STACK
2439 byte* n = NULL;
2440 byte* e = NULL;
2441 #else
2442 byte n[MAX_RSA_INT_SZ];
2443 byte e[MAX_RSA_E_SZ];
2444 #endif
2445 byte seq[MAX_SEQ_SZ];
2446 byte len[MAX_LENGTH_SZ + 1]; /* trailing 0 */
2447 int nSz;
2448 int eSz;
2449 int seqSz;
2450 int lenSz;
2451 int idx;
2452 int rawLen;
2453 int leadingBit;
2454 int err;
2455
2456 if (output == NULL || key == NULL || outLen < MAX_SEQ_SZ)
2457 return USER_CRYPTO_ERROR;
2458
2459 /* n */
2460 #ifdef WOLFSSL_SMALL_STACK
2461 n = (byte*)XMALLOC(MAX_RSA_INT_SZ, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2462 if (n == NULL)
2463 return USER_CRYPTO_ERROR;
2464 #endif
2465
2466 leadingBit = wc_Rsa_leading_bit(key->n);
2467 rawLen = wc_Rsa_unsigned_bin_size(key->n);
2468 if ((int)rawLen < 0) {
2469 return USER_CRYPTO_ERROR;
2470 }
2471
2472 rawLen = rawLen + leadingBit;
2473 n[0] = ASN_INTEGER;
2474 nSz = SetLength(rawLen, n + 1) + 1; /* int tag */
2475
2476 if ( (nSz + rawLen) < MAX_RSA_INT_SZ) {
2477 if (leadingBit)
2478 n[nSz] = 0;
2479 err = ippsGetOctString_BN((Ipp8u*)n + nSz, rawLen - leadingBit, key->n);
2480 if (err == ippStsNoErr)
2481 nSz += rawLen;
2482 else {
2483 #ifdef WOLFSSL_SMALL_STACK
2484 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2485 #endif
2486 return USER_CRYPTO_ERROR;
2487 }
2488 }
2489 else {
2490 #ifdef WOLFSSL_SMALL_STACK
2491 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2492 #endif
2493 return USER_CRYPTO_ERROR;
2494 }
2495
2496 /* e */
2497 #ifdef WOLFSSL_SMALL_STACK
2498 e = (byte*)XMALLOC(MAX_RSA_E_SZ, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2499 if (e == NULL) {
2500 #ifdef WOLFSSL_SMALL_STACK
2501 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2502 #endif
2503 return USER_CRYPTO_ERROR;
2504 }
2505 #endif
2506
2507 leadingBit = wc_Rsa_leading_bit(key->e);
2508 rawLen = wc_Rsa_unsigned_bin_size(key->e);
2509 if ((int)rawLen < 0) {
2510 return USER_CRYPTO_ERROR;
2511 }
2512
2513 rawLen = rawLen + leadingBit;
2514 e[0] = ASN_INTEGER;
2515 eSz = SetLength(rawLen, e + 1) + 1; /* int tag */
2516
2517 if ( (eSz + rawLen) < MAX_RSA_E_SZ) {
2518 if (leadingBit)
2519 e[eSz] = 0;
2520 err = ippsGetOctString_BN((Ipp8u*)e + eSz, rawLen - leadingBit, key->e);
2521 if (err == ippStsNoErr)
2522 eSz += rawLen;
2523 else {
2524 #ifdef WOLFSSL_SMALL_STACK
2525 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2526 XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2527 #endif
2528 return USER_CRYPTO_ERROR;
2529 }
2530 }
2531 else {
2532 #ifdef WOLFSSL_SMALL_STACK
2533 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2534 XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2535 #endif
2536 return USER_CRYPTO_ERROR;
2537 }
2538
2539 seqSz = SetSequence(nSz + eSz, seq);
2540
2541 /* check output size */
2542 if ( (seqSz + nSz + eSz) > outLen) {
2543 #ifdef WOLFSSL_SMALL_STACK
2544 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2545 XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2546 #endif
2547 return USER_CRYPTO_ERROR;
2548 }
2549
2550 /* headers */
2551 if (with_header) {
2552 int algoSz;
2553 #ifdef WOLFSSL_SMALL_STACK
2554 byte* algo;
2555
2556 algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2557 if (algo == NULL) {
2558 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2559 XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2560 return USER_CRYPTO_ERROR;
2561 }
2562 #else
2563 byte algo[MAX_ALGO_SZ];
2564 #endif
2565 algoSz = SetAlgoID(RSAk, algo, keyType, 0);
2566 lenSz = SetLength(seqSz + nSz + eSz + 1, len);
2567 len[lenSz++] = 0; /* trailing 0 */
2568
2569 /* write, 1 is for ASN_BIT_STRING */
2570 idx = SetSequence(nSz + eSz + seqSz + lenSz + 1 + algoSz, output);
2571
2572 /* check output size */
2573 if ( (idx + algoSz + 1 + lenSz + seqSz + nSz + eSz) > outLen) {
2574 #ifdef WOLFSSL_SMALL_STACK
2575 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2576 XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2577 XFREE(algo, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2578 #endif
2579
2580 return USER_CRYPTO_ERROR;
2581 }
2582
2583 /* algo */
2584 XMEMCPY(output + idx, algo, algoSz);
2585 idx += algoSz;
2586 /* bit string */
2587 output[idx++] = ASN_BIT_STRING;
2588 /* length */
2589 XMEMCPY(output + idx, len, lenSz);
2590 idx += lenSz;
2591 #ifdef WOLFSSL_SMALL_STACK
2592 XFREE(algo, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2593 #endif
2594 }
2595 else
2596 idx = 0;
2597
2598 /* seq */
2599 XMEMCPY(output + idx, seq, seqSz);
2600 idx += seqSz;
2601 /* n */
2602 XMEMCPY(output + idx, n, nSz);
2603 idx += nSz;
2604 /* e */
2605 XMEMCPY(output + idx, e, eSz);
2606 idx += eSz;
2607
2608 #ifdef WOLFSSL_SMALL_STACK
2609 XFREE(n, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2610 XFREE(e, NULL, DYNAMIC_TYPE_USER_CRYPTO);
2611 #endif
2612
2613 return idx;
2614 }
2615
2616
GetRsaInt(RsaKey * key,int idx)2617 static IppsBigNumState* GetRsaInt(RsaKey* key, int idx)
2618 {
2619 if (idx == 0)
2620 return key->n;
2621 if (idx == 1)
2622 return key->e;
2623 if (idx == 2)
2624 return key->dipp;
2625 if (idx == 3)
2626 return key->pipp;
2627 if (idx == 4)
2628 return key->qipp;
2629 if (idx == 5)
2630 return key->dPipp;
2631 if (idx == 6)
2632 return key->dQipp;
2633 if (idx == 7)
2634 return key->uipp;
2635
2636 return NULL;
2637 }
2638
2639
2640 /* Release Tmp RSA resources */
FreeTmpRsas(byte ** tmps,void * heap)2641 static WC_INLINE void FreeTmpRsas(byte** tmps, void* heap)
2642 {
2643 int i;
2644
2645 (void)heap;
2646
2647 for (i = 0; i < RSA_INTS; i++)
2648 XFREE(tmps[i], heap, DYNAMIC_TYPE_USER_CRYPTO);
2649 }
2650
2651
2652 /* Convert RsaKey key to DER format, write to output (inLen), return bytes
2653 written */
wc_RsaKeyToDer(RsaKey * key,byte * output,word32 inLen)2654 int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen)
2655 {
2656 word32 seqSz, verSz, rawLen, intTotalLen = 0;
2657 word32 sizes[RSA_INTS];
2658 int i, j, outLen, ret = 0, lbit;
2659
2660 byte seq[MAX_SEQ_SZ];
2661 byte ver[MAX_VERSION_SZ];
2662 byte* tmps[RSA_INTS];
2663
2664 USER_DEBUG(("Entering RsaKeyToDer\n"));
2665
2666 if (!key)
2667 return USER_CRYPTO_ERROR;
2668
2669 if (key->type != RSA_PRIVATE)
2670 return USER_CRYPTO_ERROR;
2671
2672 for (i = 0; i < RSA_INTS; i++)
2673 tmps[i] = NULL;
2674
2675 /* write all big ints from key to DER tmps */
2676 for (i = 0; i < RSA_INTS; i++) {
2677 Ipp32u isZero;
2678 IppsBigNumState* keyInt = GetRsaInt(key, i);
2679
2680 ippsCmpZero_BN(keyInt, &isZero); /* makes isZero 0 if true */
2681 rawLen = wc_Rsa_unsigned_bin_size(keyInt);
2682 if ((int)rawLen < 0) {
2683 return USER_CRYPTO_ERROR;
2684 }
2685
2686 /* leading zero */
2687 if (!isZero || wc_Rsa_leading_bit(keyInt))
2688 lbit = 1;
2689 else
2690 lbit = 0;
2691
2692 rawLen += lbit;
2693
2694 tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap,
2695 DYNAMIC_TYPE_USER_CRYPTO);
2696 if (tmps[i] == NULL) {
2697 ret = USER_CRYPTO_ERROR;
2698 break;
2699 }
2700
2701 tmps[i][0] = ASN_INTEGER;
2702 sizes[i] = SetLength(rawLen, tmps[i] + 1) + 1 + lbit; /* tag & lbit */
2703
2704 if (sizes[i] <= MAX_SEQ_SZ) {
2705 int err;
2706
2707 /* leading zero */
2708 if (lbit)
2709 tmps[i][sizes[i]-1] = 0x00;
2710
2711 /* extract data*/
2712 err = ippsGetOctString_BN((Ipp8u*)(tmps[i] + sizes[i]),
2713 rawLen - lbit, keyInt);
2714 if (err == ippStsOk) {
2715 sizes[i] += (rawLen-lbit); /* lbit included in rawLen */
2716 intTotalLen += sizes[i];
2717 ret = 0;
2718 }
2719 else {
2720 ret = USER_CRYPTO_ERROR;
2721 USER_DEBUG(("ippsGetOctString_BN error %s\n",
2722 ippGetStatusString(err)));
2723 break;
2724 }
2725 }
2726 else {
2727 ret = USER_CRYPTO_ERROR;
2728 break;
2729 }
2730 }
2731
2732 if (ret != 0) {
2733 FreeTmpRsas(tmps, key->heap);
2734 return ret;
2735 }
2736
2737 /* make headers */
2738 verSz = SetMyVersion(0, ver, FALSE);
2739 seqSz = SetSequence(verSz + intTotalLen, seq);
2740
2741 outLen = seqSz + verSz + intTotalLen;
2742 if (output) {
2743 if (outLen > (int)inLen) {
2744 return USER_CRYPTO_ERROR;
2745 }
2746
2747 /* write to output */
2748 XMEMCPY(output, seq, seqSz);
2749 j = seqSz;
2750 XMEMCPY(output + j, ver, verSz);
2751 j += verSz;
2752
2753 for (i = 0; i < RSA_INTS; i++) {
2754 XMEMCPY(output + j, tmps[i], sizes[i]);
2755 j += sizes[i];
2756 }
2757 }
2758 FreeTmpRsas(tmps, key->heap);
2759
2760 return outLen;
2761 }
2762
2763
2764 /* Convert Rsa Public key to DER format, write to output (inLen), return bytes
2765 written
2766 */
wc_RsaKeyToPublicDer(RsaKey * key,byte * output,word32 inLen)2767 int wc_RsaKeyToPublicDer(RsaKey* key, byte* output, word32 inLen)
2768 {
2769 return SetRsaPublicKey(output, key, inLen, 1);
2770 }
2771
2772 /* Returns public DER version of the RSA key. If with_header is 0 then only a
2773 * seq + n + e is returned in ASN.1 DER format */
wc_RsaKeyToPublicDer_ex(RsaKey * key,byte * output,word32 inLen,int with_header)2774 int wc_RsaKeyToPublicDer_ex(RsaKey* key, byte* output, word32 inLen,
2775 int with_header)
2776 {
2777 return SetRsaPublicKey(output, key, inLen, with_header);
2778 }
2779
2780 #endif /* WOLFSSL_KEY_GEN || OPENSSL_EXTRA */
2781
2782 #ifdef WC_RSA_BLINDING
2783
wc_RsaSetRNG(RsaKey * key,WC_RNG * rng)2784 int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
2785 {
2786 if (key == NULL)
2787 return USER_CRYPTO_ERROR;
2788
2789 (void)rng;
2790
2791 return 0;
2792 }
2793
2794 #endif /* WC_RSA_BLINDING */
2795
2796 #endif /* NO_RSA */
2797
2798