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