wolf SSL / wolfSSL-TLS13-Beta

Fork of wolfSSL by wolf SSL

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rsa.c Source File

rsa.c

00001 /* rsa.c
00002  *
00003  * Copyright (C) 2006-2016 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfssl/wolfcrypt/settings.h>
00028 
00029 #ifndef NO_RSA
00030 
00031 #include <wolfssl/wolfcrypt/rsa.h>
00032 
00033 /*
00034 Possible RSA enable options:
00035  * NO_RSA:              Overall control of RSA                      default: on (not defined)
00036  * WC_RSA_BLINDING:     Uses Blinding w/ Private Ops                default: off
00037                         Note: slower by ~20%
00038  * WOLFSSL_KEY_GEN:     Allows Private Key Generation               default: off
00039  * RSA_LOW_MEM:         NON CRT Private Operations, less memory     default: off
00040  * WC_NO_RSA_OAEP:      Disables RSA OAEP padding                   default: on (not defined)
00041 
00042 */
00043 
00044 /*
00045 RSA Key Size Configuration:
00046  * FP_MAX_BITS:         With USE_FAST_MATH only                     default: 4096
00047     If USE_FAST_MATH then use this to override default.
00048     Value is key size * 2. Example: RSA 3072 = 6144
00049 */
00050 
00051 
00052 #ifdef HAVE_FIPS
00053 int  wc_InitRsaKey(RsaKey* key, void* ptr)
00054 {
00055     return InitRsaKey_fips(key, ptr);
00056 }
00057 
00058 int  wc_InitRsaKey_ex(RsaKey* key, void* ptr, int devId)
00059 {
00060     (void)devId;
00061     return InitRsaKey_fips(key, ptr);
00062 }
00063 
00064 int  wc_FreeRsaKey(RsaKey* key)
00065 {
00066     return FreeRsaKey_fips(key);
00067 }
00068 
00069 
00070 int  wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
00071                                  word32 outLen, RsaKey* key, WC_RNG* rng)
00072 {
00073     return RsaPublicEncrypt_fips(in, inLen, out, outLen, key, rng);
00074 }
00075 
00076 
00077 int  wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,
00078                                         RsaKey* key)
00079 {
00080     return RsaPrivateDecryptInline_fips(in, inLen, out, key);
00081 }
00082 
00083 
00084 int  wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
00085                                   word32 outLen, RsaKey* key)
00086 {
00087     return RsaPrivateDecrypt_fips(in, inLen, out, outLen, key);
00088 }
00089 
00090 
00091 int  wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
00092                             word32 outLen, RsaKey* key, WC_RNG* rng)
00093 {
00094     return RsaSSL_Sign_fips(in, inLen, out, outLen, key, rng);
00095 }
00096 
00097 
00098 int  wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
00099 {
00100     return RsaSSL_VerifyInline_fips(in, inLen, out, key);
00101 }
00102 
00103 
00104 int  wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
00105                               word32 outLen, RsaKey* key)
00106 {
00107     return RsaSSL_Verify_fips(in, inLen, out, outLen, key);
00108 }
00109 
00110 
00111 int  wc_RsaEncryptSize(RsaKey* key)
00112 {
00113     return RsaEncryptSize_fips(key);
00114 }
00115 
00116 
00117 int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,
00118                            word32* bSz)
00119 {
00120     /* not specified as fips so not needing _fips */
00121     return RsaFlattenPublicKey(key, a, aSz, b, bSz);
00122 }
00123 #ifdef WOLFSSL_KEY_GEN
00124     int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
00125     {
00126         return MakeRsaKey(key, size, e, rng);
00127     }
00128 #endif
00129 
00130 
00131 /* these are functions in asn and are routed to wolfssl/wolfcrypt/asn.c
00132 * wc_RsaPrivateKeyDecode
00133 * wc_RsaPublicKeyDecode
00134 */
00135 
00136 #else /* else build without fips */
00137 
00138 #include <wolfssl/wolfcrypt/random.h>
00139 #include <wolfssl/wolfcrypt/error-crypt.h>
00140 #include <wolfssl/wolfcrypt/logging.h>
00141 #ifdef NO_INLINE
00142     #include <wolfssl/wolfcrypt/misc.h>
00143 #else
00144     #define WOLFSSL_MISC_INCLUDED
00145     #include <wolfcrypt/src/misc.c>
00146 #endif
00147 
00148 #define ERROR_OUT(x) { ret = (x); goto done;}
00149 
00150 
00151 enum {
00152     RSA_STATE_NONE = 0,
00153 
00154     RSA_STATE_ENCRYPT_PAD,
00155     RSA_STATE_ENCRYPT_EXPTMOD,
00156     RSA_STATE_ENCRYPT_RES,
00157 
00158     RSA_STATE_DECRYPT_EXPTMOD,
00159     RSA_STATE_DECRYPT_UNPAD,
00160     RSA_STATE_DECRYPT_RES,
00161 };
00162 
00163 static void wc_RsaCleanup(RsaKey* key)
00164 {
00165     if (key && key->data) {
00166         /* make sure any allocated memory is free'd */
00167         if (key->dataIsAlloc) {
00168             if (key->type == RSA_PRIVATE_DECRYPT ||
00169                 key->type == RSA_PRIVATE_ENCRYPT) {
00170                 ForceZero(key->data, key->dataLen);
00171             }
00172             XFREE(key->data, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);
00173             key->dataIsAlloc = 0;
00174         }
00175         key->data = NULL;
00176         key->dataLen = 0;
00177     }
00178 }
00179 
00180 int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId)
00181 {
00182     int ret = 0;
00183 
00184     if (key == NULL) {
00185         return BAD_FUNC_ARG;
00186     }
00187 
00188     key->type = RSA_TYPE_UNKNOWN;
00189     key->state = RSA_STATE_NONE;
00190     key->heap = heap;
00191     key->data = NULL;
00192     key->dataLen = 0;
00193     key->dataIsAlloc = 0;
00194 #ifdef WC_RSA_BLINDING
00195     key->rng = NULL;
00196 #endif
00197 
00198 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
00199     /* handle as async */
00200     ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA,
00201                                                             key->heap, devId);
00202     #ifdef WOLFSSL_CERT_GEN
00203         XMEMSET(&key->certSignCtx, 0, sizeof(CertSignCtx));
00204     #endif
00205 #else
00206     (void)devId;
00207 #endif
00208 
00209     mp_init(&key->n);
00210     mp_init(&key->e);
00211     mp_init(&key->d);
00212     mp_init(&key->p);
00213     mp_init(&key->q);
00214     mp_init(&key->dP);
00215     mp_init(&key->dQ);
00216     mp_init(&key->u);
00217 
00218     return ret;
00219 }
00220 
00221 int wc_InitRsaKey(RsaKey* key, void* heap)
00222 {
00223     return wc_InitRsaKey_ex(key, heap, INVALID_DEVID);
00224 }
00225 
00226 int wc_FreeRsaKey(RsaKey* key)
00227 {
00228     int ret = 0;
00229 
00230     if (key == NULL) {
00231         return BAD_FUNC_ARG;
00232     }
00233 
00234     wc_RsaCleanup(key);
00235 
00236 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
00237     wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA);
00238 #endif
00239 
00240     if (key->type == RSA_PRIVATE) {
00241         mp_forcezero(&key->u);
00242         mp_forcezero(&key->dQ);
00243         mp_forcezero(&key->dP);
00244         mp_forcezero(&key->q);
00245         mp_forcezero(&key->p);
00246         mp_forcezero(&key->d);
00247     }
00248     /* private part */
00249     mp_clear(&key->u);
00250     mp_clear(&key->dQ);
00251     mp_clear(&key->dP);
00252     mp_clear(&key->q);
00253     mp_clear(&key->p);
00254     mp_clear(&key->d);
00255 
00256     /* public part */
00257     mp_clear(&key->e);
00258     mp_clear(&key->n);
00259 
00260     return ret;
00261 }
00262 
00263 
00264 #if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_PSS)
00265 /* Uses MGF1 standard as a mask generation function
00266    hType: hash type used
00267    seed:  seed to use for generating mask
00268    seedSz: size of seed buffer
00269    out:   mask output after generation
00270    outSz: size of output buffer
00271  */
00272 static int RsaMGF1(enum wc_HashType hType, byte* seed, word32 seedSz,
00273                                         byte* out, word32 outSz, void* heap)
00274 {
00275     byte* tmp;
00276     /* needs to be large enough for seed size plus counter(4) */
00277     byte  tmpA[WC_MAX_DIGEST_SIZE + 4];
00278     byte   tmpF;     /* 1 if dynamic memory needs freed */
00279     word32 tmpSz;
00280     int hLen;
00281     int ret;
00282     word32 counter;
00283     word32 idx;
00284     hLen    = wc_HashGetDigestSize(hType);
00285     counter = 0;
00286     idx     = 0;
00287 
00288     (void)heap;
00289 
00290     /* check error return of wc_HashGetDigestSize */
00291     if (hLen < 0) {
00292         return hLen;
00293     }
00294 
00295     /* if tmp is not large enough than use some dynamic memory */
00296     if ((seedSz + 4) > sizeof(tmpA) || (word32)hLen > sizeof(tmpA)) {
00297         /* find largest amount of memory needed which will be the max of
00298          * hLen and (seedSz + 4) since tmp is used to store the hash digest */
00299         tmpSz = ((seedSz + 4) > (word32)hLen)? seedSz + 4: (word32)hLen;
00300         tmp = (byte*)XMALLOC(tmpSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
00301         if (tmp == NULL) {
00302             return MEMORY_E;
00303         }
00304         tmpF = 1; /* make sure to free memory when done */
00305     }
00306     else {
00307         /* use array on the stack */
00308         tmpSz = sizeof(tmpA);
00309         tmp  = tmpA;
00310         tmpF = 0; /* no need to free memory at end */
00311     }
00312 
00313     do {
00314         int i = 0;
00315         XMEMCPY(tmp, seed, seedSz);
00316 
00317         /* counter to byte array appended to tmp */
00318         tmp[seedSz]     = (counter >> 24) & 0xFF;
00319         tmp[seedSz + 1] = (counter >> 16) & 0xFF;
00320         tmp[seedSz + 2] = (counter >>  8) & 0xFF;
00321         tmp[seedSz + 3] = (counter)       & 0xFF;
00322 
00323         /* hash and append to existing output */
00324         if ((ret = wc_Hash(hType, tmp, (seedSz + 4), tmp, tmpSz)) != 0) {
00325             /* check for if dynamic memory was needed, then free */
00326             if (tmpF) {
00327                 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
00328             }
00329             return ret;
00330         }
00331 
00332         for (i = 0; i < hLen && idx < outSz; i++) {
00333             out[idx++] = tmp[i];
00334         }
00335         counter++;
00336     } while (idx < outSz);
00337 
00338     /* check for if dynamic memory was needed, then free */
00339     if (tmpF) {
00340         XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
00341     }
00342 
00343     return 0;
00344 }
00345 
00346 /* helper function to direct which mask generation function is used
00347    switeched on type input
00348  */
00349 static int RsaMGF(int type, byte* seed, word32 seedSz, byte* out,
00350                                                     word32 outSz, void* heap)
00351 {
00352     int ret;
00353 
00354     switch(type) {
00355     #ifndef NO_SHA
00356         case WC_MGF1SHA1:
00357             ret = RsaMGF1(WC_HASH_TYPE_SHA, seed, seedSz, out, outSz, heap);
00358             break;
00359     #endif
00360     #ifndef NO_SHA256
00361     #ifdef WOLFSSL_SHA224
00362         case WC_MGF1SHA224:
00363             ret = RsaMGF1(WC_HASH_TYPE_SHA224, seed, seedSz, out, outSz, heap);
00364             break;
00365     #endif
00366         case WC_MGF1SHA256:
00367             ret = RsaMGF1(WC_HASH_TYPE_SHA256, seed, seedSz, out, outSz, heap);
00368             break;
00369     #endif
00370     #ifdef WOLFSSL_SHA512
00371     #ifdef WOLFSSL_SHA384
00372         case WC_MGF1SHA384:
00373             ret = RsaMGF1(WC_HASH_TYPE_SHA384, seed, seedSz, out, outSz, heap);
00374             break;
00375     #endif
00376         case WC_MGF1SHA512:
00377             ret = RsaMGF1(WC_HASH_TYPE_SHA512, seed, seedSz, out, outSz, heap);
00378             break;
00379     #endif
00380         default:
00381             WOLFSSL_MSG("Unknown MGF type: check build options");
00382             ret = BAD_FUNC_ARG;
00383     }
00384 
00385     /* in case of default avoid unused warning */
00386     (void)seed;
00387     (void)seedSz;
00388     (void)out;
00389     (void)outSz;
00390     (void)heap;
00391 
00392     return ret;
00393 }
00394 #endif /* !WC_NO_RSA_OAEP */
00395 
00396 
00397 /* Padding */
00398 #ifndef WC_NO_RSA_OAEP
00399 static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
00400         word32 pkcsBlockLen, byte padValue, WC_RNG* rng,
00401         enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen,
00402         void* heap)
00403 {
00404     int ret;
00405     int hLen;
00406     int psLen;
00407     int i;
00408     word32 idx;
00409 
00410     byte* dbMask;
00411 
00412     #ifdef WOLFSSL_SMALL_STACK
00413         byte* lHash = NULL;
00414         byte* seed  = NULL;
00415     #else
00416         /* must be large enough to contain largest hash */
00417         byte lHash[WC_MAX_DIGEST_SIZE];
00418         byte seed[ WC_MAX_DIGEST_SIZE];
00419     #endif
00420 
00421     /* no label is allowed, but catch if no label provided and length > 0 */
00422     if (optLabel == NULL && labelLen > 0) {
00423         return BUFFER_E;
00424     }
00425 
00426     /* limit of label is the same as limit of hash function which is massive */
00427     hLen = wc_HashGetDigestSize(hType);
00428     if (hLen < 0) {
00429         return hLen;
00430     }
00431 
00432     #ifdef WOLFSSL_SMALL_STACK
00433         lHash = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
00434         if (lHash == NULL) {
00435             return MEMORY_E;
00436         }
00437         seed = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
00438         if (seed == NULL) {
00439             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00440             return MEMORY_E;
00441         }
00442     #else
00443         /* hLen should never be larger than lHash since size is max digest size,
00444            but check before blindly calling wc_Hash */
00445         if ((word32)hLen > sizeof(lHash)) {
00446             WOLFSSL_MSG("OAEP lHash to small for digest!!");
00447             return MEMORY_E;
00448         }
00449     #endif
00450 
00451     if ((ret = wc_Hash(hType, optLabel, labelLen, lHash, hLen)) != 0) {
00452         WOLFSSL_MSG("OAEP hash type possibly not supported or lHash to small");
00453         #ifdef WOLFSSL_SMALL_STACK
00454             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00455             XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00456         #endif
00457         return ret;
00458     }
00459 
00460     /* handles check of location for idx as well as psLen, cast to int to check
00461        for pkcsBlockLen(k) - 2 * hLen - 2 being negative
00462        This check is similar to decryption where k > 2 * hLen + 2 as msg
00463        size aproaches 0. In decryption if k is less than or equal -- then there
00464        is no possible room for msg.
00465        k = RSA key size
00466        hLen = hash digest size -- will always be >= 0 at this point
00467      */
00468     if ((word32)(2 * hLen + 2) > pkcsBlockLen) {
00469         WOLFSSL_MSG("OAEP pad error hash to big for RSA key size");
00470         #ifdef WOLFSSL_SMALL_STACK
00471             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00472             XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00473         #endif
00474         return BAD_FUNC_ARG;
00475     }
00476 
00477     if (inputLen > (pkcsBlockLen - 2 * hLen - 2)) {
00478         WOLFSSL_MSG("OAEP pad error message too long");
00479         #ifdef WOLFSSL_SMALL_STACK
00480             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00481             XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00482         #endif
00483         return BAD_FUNC_ARG;
00484     }
00485 
00486     /* concatenate lHash || PS || 0x01 || msg */
00487     idx = pkcsBlockLen - 1 - inputLen;
00488     psLen = pkcsBlockLen - inputLen - 2 * hLen - 2;
00489     if (pkcsBlockLen < inputLen) { /*make sure not writing over end of buffer */
00490         #ifdef WOLFSSL_SMALL_STACK
00491             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00492             XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00493         #endif
00494         return BUFFER_E;
00495     }
00496     XMEMCPY(pkcsBlock + (pkcsBlockLen - inputLen), input, inputLen);
00497     pkcsBlock[idx--] = 0x01; /* PS and M separator */
00498     while (psLen > 0 && idx > 0) {
00499         pkcsBlock[idx--] = 0x00;
00500         psLen--;
00501     }
00502 
00503     idx = idx - hLen + 1;
00504     XMEMCPY(pkcsBlock + idx, lHash, hLen);
00505 
00506     /* generate random seed */
00507     if ((ret = wc_RNG_GenerateBlock(rng, seed, hLen)) != 0) {
00508         #ifdef WOLFSSL_SMALL_STACK
00509             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00510             XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00511         #endif
00512         return ret;
00513     }
00514 
00515     /* create maskedDB from dbMask */
00516     dbMask = (byte*)XMALLOC(pkcsBlockLen - hLen - 1, heap, DYNAMIC_TYPE_RSA);
00517     if (dbMask == NULL) {
00518         #ifdef WOLFSSL_SMALL_STACK
00519             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00520             XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00521         #endif
00522         return MEMORY_E;
00523     }
00524     XMEMSET(dbMask, 0, pkcsBlockLen - hLen - 1); /* help static analyzer */
00525 
00526     ret = RsaMGF(mgf, seed, hLen, dbMask, pkcsBlockLen - hLen - 1, heap);
00527     if (ret != 0) {
00528         XFREE(dbMask, heap, DYNAMIC_TYPE_RSA);
00529         #ifdef WOLFSSL_SMALL_STACK
00530             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00531             XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00532         #endif
00533         return ret;
00534     }
00535 
00536     i = 0;
00537     idx = hLen + 1;
00538     while (idx < pkcsBlockLen && (word32)i < (pkcsBlockLen - hLen -1)) {
00539         pkcsBlock[idx] = dbMask[i++] ^ pkcsBlock[idx];
00540         idx++;
00541     }
00542     XFREE(dbMask, heap, DYNAMIC_TYPE_RSA);
00543 
00544 
00545     /* create maskedSeed from seedMask */
00546     idx = 0;
00547     pkcsBlock[idx++] = 0x00;
00548     /* create seedMask inline */
00549     if ((ret = RsaMGF(mgf, pkcsBlock + hLen + 1, pkcsBlockLen - hLen - 1,
00550                                            pkcsBlock + 1, hLen, heap)) != 0) {
00551         #ifdef WOLFSSL_SMALL_STACK
00552             XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00553             XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00554         #endif
00555         return ret;
00556     }
00557 
00558     /* xor created seedMask with seed to make maskedSeed */
00559     i = 0;
00560     while (idx < (word32)(hLen + 1) && i < hLen) {
00561         pkcsBlock[idx] = pkcsBlock[idx] ^ seed[i++];
00562         idx++;
00563     }
00564 
00565     #ifdef WOLFSSL_SMALL_STACK
00566         XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
00567         XFREE(seed,  heap, DYNAMIC_TYPE_TMP_BUFFER);
00568     #endif
00569     (void)padValue;
00570 
00571     return 0;
00572 }
00573 #endif /* !WC_NO_RSA_OAEP */
00574 
00575 #ifdef WC_RSA_PSS
00576 static int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock,
00577         word32 pkcsBlockLen, WC_RNG* rng, enum wc_HashType hType, int mgf,
00578         void* heap)
00579 {
00580     int   ret;
00581     int   hLen, i;
00582     byte* s;
00583     byte* m;
00584     byte* h;
00585     byte  salt[WC_MAX_DIGEST_SIZE];
00586 
00587     hLen = wc_HashGetDigestSize(hType);
00588     if (hLen < 0)
00589         return hLen;
00590 
00591     s = m = pkcsBlock;
00592     XMEMSET(m, 0, 8);
00593     m += 8;
00594     XMEMCPY(m, input, inputLen);
00595     m += inputLen;
00596     if ((ret = wc_RNG_GenerateBlock(rng, salt, hLen)) != 0)
00597         return ret;
00598     XMEMCPY(m, salt, hLen);
00599     m += hLen;
00600 
00601     h = pkcsBlock + pkcsBlockLen - 1 - hLen;
00602     if ((ret = wc_Hash(hType, s, (word32)(m - s), h, hLen)) != 0)
00603         return ret;
00604     pkcsBlock[pkcsBlockLen - 1] = 0xbc;
00605 
00606     ret = RsaMGF(mgf, h, hLen, pkcsBlock, pkcsBlockLen - hLen - 1, heap);
00607     if (ret != 0)
00608         return ret;
00609     pkcsBlock[0] &= 0x7f;
00610 
00611     m = pkcsBlock + pkcsBlockLen - 1 - hLen - hLen - 1;
00612     *(m++) ^= 0x01;
00613     for (i = 0; i < hLen; i++)
00614         m[i] ^= salt[i];
00615 
00616     return 0;
00617 }
00618 #endif
00619 
00620 static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
00621                            word32 pkcsBlockLen, byte padValue, WC_RNG* rng)
00622 {
00623     if (input == NULL || inputLen == 0 || pkcsBlock == NULL ||
00624                                                         pkcsBlockLen == 0) {
00625         return BAD_FUNC_ARG;
00626     }
00627 
00628     pkcsBlock[0] = 0x0;       /* set first byte to zero and advance */
00629     pkcsBlock++; pkcsBlockLen--;
00630     pkcsBlock[0] = padValue;  /* insert padValue */
00631 
00632     if (padValue == RSA_BLOCK_TYPE_1) {
00633         if (pkcsBlockLen < inputLen + 2) {
00634             WOLFSSL_MSG("RsaPad error, invalid length");
00635             return RSA_PAD_E;
00636         }
00637 
00638         /* pad with 0xff bytes */
00639         XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
00640     }
00641     else {
00642         /* pad with non-zero random bytes */
00643         word32 padLen, i;
00644         int    ret;
00645 
00646         if (pkcsBlockLen < inputLen + 1) {
00647             WOLFSSL_MSG("RsaPad error, invalid length");
00648             return RSA_PAD_E;
00649         }
00650 
00651         padLen = pkcsBlockLen - inputLen - 1;
00652         ret    = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);
00653         if (ret != 0) {
00654             return ret;
00655         }
00656 
00657         /* remove zeros */
00658         for (i = 1; i < padLen; i++) {
00659             if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
00660         }
00661     }
00662 
00663     pkcsBlock[pkcsBlockLen-inputLen-1] = 0;     /* separator */
00664     XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
00665 
00666     return 0;
00667 }
00668 
00669 /* helper function to direct which padding is used */
00670 static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
00671     word32 pkcsBlockLen, byte padValue, WC_RNG* rng, int padType,
00672     enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen,
00673     void* heap)
00674 {
00675     int ret;
00676 
00677     switch (padType)
00678     {
00679         case WC_RSA_PKCSV15_PAD:
00680             /*WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding");*/
00681             ret = RsaPad(input, inputLen, pkcsBlock, pkcsBlockLen,
00682                                                                  padValue, rng);
00683             break;
00684 
00685     #ifndef WC_NO_RSA_OAEP
00686         case WC_RSA_OAEP_PAD:
00687             WOLFSSL_MSG("wolfSSL Using RSA OAEP padding");
00688             ret = RsaPad_OAEP(input, inputLen, pkcsBlock, pkcsBlockLen,
00689                            padValue, rng, hType, mgf, optLabel, labelLen, heap);
00690             break;
00691     #endif
00692 
00693     #ifdef WC_RSA_PSS
00694         case WC_RSA_PSS_PAD:
00695             WOLFSSL_MSG("wolfSSL Using RSA PSS padding");
00696             ret = RsaPad_PSS(input, inputLen, pkcsBlock, pkcsBlockLen,
00697                                                          rng, hType, mgf, heap);
00698             break;
00699     #endif
00700 
00701         default:
00702             WOLFSSL_MSG("Unknown RSA Pad Type");
00703             ret = RSA_PAD_E;
00704     }
00705 
00706     /* silence warning if not used with padding scheme */
00707     (void)hType;
00708     (void)mgf;
00709     (void)optLabel;
00710     (void)labelLen;
00711     (void)heap;
00712 
00713     return ret;
00714 }
00715 
00716 
00717 /* UnPadding */
00718 #ifndef WC_NO_RSA_OAEP
00719 /* UnPad plaintext, set start to *output, return length of plaintext,
00720  * < 0 on error */
00721 static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
00722                             byte **output, enum wc_HashType hType, int mgf,
00723                             byte* optLabel, word32 labelLen, void* heap)
00724 {
00725     int hLen;
00726     int ret;
00727     byte h[WC_MAX_DIGEST_SIZE]; /* max digest size */
00728     byte* tmp;
00729     word32 idx;
00730 
00731     /* no label is allowed, but catch if no label provided and length > 0 */
00732     if (optLabel == NULL && labelLen > 0) {
00733         return BUFFER_E;
00734     }
00735 
00736     hLen = wc_HashGetDigestSize(hType);
00737     if ((hLen < 0) || (pkcsBlockLen < (2 * (word32)hLen + 2))) {
00738         return BAD_FUNC_ARG;
00739     }
00740 
00741     tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
00742     if (tmp == NULL) {
00743         return MEMORY_E;
00744     }
00745     XMEMSET(tmp, 0, pkcsBlockLen);
00746 
00747     /* find seedMask value */
00748     if ((ret = RsaMGF(mgf, (byte*)(pkcsBlock + (hLen + 1)),
00749                             pkcsBlockLen - hLen - 1, tmp, hLen, heap)) != 0) {
00750         XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
00751         return ret;
00752     }
00753 
00754     /* xor seedMask value with maskedSeed to get seed value */
00755     for (idx = 0; idx < (word32)hLen; idx++) {
00756         tmp[idx] = tmp[idx] ^ pkcsBlock[1 + idx];
00757     }
00758 
00759     /* get dbMask value */
00760     if ((ret = RsaMGF(mgf, tmp, hLen, tmp + hLen,
00761                                        pkcsBlockLen - hLen - 1, heap)) != 0) {
00762         XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00763         return ret;
00764     }
00765 
00766     /* get DB value by doing maskedDB xor dbMask */
00767     for (idx = 0; idx < (pkcsBlockLen - hLen - 1); idx++) {
00768         pkcsBlock[hLen + 1 + idx] = pkcsBlock[hLen + 1 + idx] ^ tmp[idx + hLen];
00769     }
00770 
00771     /* done with use of tmp buffer */
00772     XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
00773 
00774     /* advance idx to index of PS and msg separator, account for PS size of 0*/
00775     idx = hLen + 1 + hLen;
00776     while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;}
00777 
00778     /* create hash of label for comparision with hash sent */
00779     if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) {
00780         return ret;
00781     }
00782 
00783     /* say no to chosen ciphertext attack.
00784        Comparison of lHash, Y, and separator value needs to all happen in
00785        constant time.
00786        Attackers should not be able to get error condition from the timing of
00787        these checks.
00788      */
00789     ret = 0;
00790     ret |= ConstantCompare(pkcsBlock + hLen + 1, h, hLen);
00791     ret += pkcsBlock[idx++] ^ 0x01; /* separator value is 0x01 */
00792     ret += pkcsBlock[0]     ^ 0x00; /* Y, the first value, should be 0 */
00793 
00794     if (ret != 0) {
00795         return BAD_PADDING_E;
00796     }
00797 
00798     /* adjust pointer to correct location in array and return size of M */
00799     *output = (byte*)(pkcsBlock + idx);
00800     return pkcsBlockLen - idx;
00801 }
00802 #endif /* WC_NO_RSA_OAEP */
00803 
00804 #ifdef WC_RSA_PSS
00805 static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
00806                         byte **output, enum wc_HashType hType, int mgf,
00807                         void* heap)
00808 {
00809     int   ret;
00810     byte* tmp;
00811     int   hLen, i;
00812 
00813     hLen = wc_HashGetDigestSize(hType);
00814     if (hLen < 0)
00815         return hLen;
00816 
00817     if (pkcsBlock[pkcsBlockLen - 1] != 0xbc)
00818         return BAD_PADDING_E;
00819 
00820     tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
00821     if (tmp == NULL) {
00822         return MEMORY_E;
00823     }
00824 
00825     if ((ret = RsaMGF(mgf, pkcsBlock + pkcsBlockLen - 1 - hLen, hLen,
00826                                     tmp, pkcsBlockLen - 1 - hLen, heap)) != 0) {
00827         XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
00828         return ret;
00829     }
00830 
00831     tmp[0] &= 0x7f;
00832     for (i = 0; i < (int)(pkcsBlockLen - 1 - hLen - hLen - 1); i++) {
00833         if (tmp[i] != pkcsBlock[i]) {
00834             XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
00835             return BAD_PADDING_E;
00836         }
00837     }
00838     if (tmp[i] != (pkcsBlock[i] ^ 0x01)) {
00839         XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
00840         return BAD_PADDING_E;
00841     }
00842     for (i++; i < (int)(pkcsBlockLen - 1 - hLen); i++)
00843         pkcsBlock[i] ^= tmp[i];
00844 
00845     XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
00846 
00847     *output = pkcsBlock + i;
00848     return hLen;
00849 }
00850 #endif
00851 
00852 /* UnPad plaintext, set start to *output, return length of plaintext,
00853  * < 0 on error */
00854 static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
00855                                                byte **output, byte padValue)
00856 {
00857     word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0;
00858     word32 invalid = 0;
00859     word32 i = 1;
00860     word32 outputLen;
00861 
00862     if (output == NULL || pkcsBlockLen == 0) {
00863         return BAD_FUNC_ARG;
00864     }
00865 
00866     if (pkcsBlock[0] != 0x0) { /* skip past zero */
00867         invalid = 1;
00868     }
00869     pkcsBlock++; pkcsBlockLen--;
00870 
00871     /* Require block type padValue */
00872     invalid = (pkcsBlock[0] != padValue) || invalid;
00873 
00874     /* verify the padding until we find the separator */
00875     if (padValue == RSA_BLOCK_TYPE_1) {
00876         while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
00877     }
00878     else {
00879         while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
00880     }
00881 
00882     if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
00883         WOLFSSL_MSG("RsaUnPad error, bad formatting");
00884         return RSA_PAD_E;
00885     }
00886 
00887     outputLen = pkcsBlockLen - i;
00888     invalid = (outputLen > maxOutputLen) || invalid;
00889 
00890     if (invalid) {
00891         WOLFSSL_MSG("RsaUnPad error, invalid formatting");
00892         return RSA_PAD_E;
00893     }
00894 
00895     *output = (byte *)(pkcsBlock + i);
00896     return outputLen;
00897 }
00898 
00899 /* helper function to direct unpadding */
00900 static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
00901                           byte padValue, int padType, enum wc_HashType hType,
00902                           int mgf, byte* optLabel, word32 labelLen, void* heap)
00903 {
00904     int ret;
00905 
00906     switch (padType) {
00907         case WC_RSA_PKCSV15_PAD:
00908             /*WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 un-padding");*/
00909             ret = RsaUnPad(pkcsBlock, pkcsBlockLen, out, padValue);
00910             break;
00911 
00912     #ifndef WC_NO_RSA_OAEP
00913         case WC_RSA_OAEP_PAD:
00914             WOLFSSL_MSG("wolfSSL Using RSA OAEP un-padding");
00915             ret = RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out,
00916                                         hType, mgf, optLabel, labelLen, heap);
00917             break;
00918     #endif
00919 
00920     #ifdef WC_RSA_PSS
00921         case WC_RSA_PSS_PAD:
00922             WOLFSSL_MSG("wolfSSL Using RSA PSS un-padding");
00923             ret = RsaUnPad_PSS((byte*)pkcsBlock, pkcsBlockLen, out, hType, mgf,
00924                                                                           heap);
00925             break;
00926     #endif
00927 
00928         default:
00929             WOLFSSL_MSG("Unknown RSA UnPad Type");
00930             ret = RSA_PAD_E;
00931     }
00932 
00933     /* silence warning if not used with padding scheme */
00934     (void)hType;
00935     (void)mgf;
00936     (void)optLabel;
00937     (void)labelLen;
00938     (void)heap;
00939 
00940     return ret;
00941 }
00942 
00943 static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
00944                           word32* outLen, int type, RsaKey* key, WC_RNG* rng)
00945 {
00946     mp_int tmp;
00947 #ifdef WC_RSA_BLINDING
00948     mp_int rnd, rndi;
00949 #endif
00950     int    ret = 0;
00951     word32 keyLen, len;
00952 
00953     (void)rng;
00954 
00955     if (mp_init(&tmp) != MP_OKAY)
00956         return MP_INIT_E;
00957 
00958 #ifdef WC_RSA_BLINDING
00959     if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
00960         if (mp_init_multi(&rnd, &rndi, NULL, NULL, NULL, NULL) != MP_OKAY) {
00961             mp_clear(&tmp);
00962             return MP_INIT_E;
00963         }
00964     }
00965 #endif
00966 
00967     if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
00968         ERROR_OUT(MP_READ_E);
00969 
00970     switch(type) {
00971     case RSA_PRIVATE_DECRYPT:
00972     case RSA_PRIVATE_ENCRYPT:
00973     {
00974     #ifdef WC_RSA_BLINDING
00975         /* blind */
00976         ret = mp_rand(&rnd, get_digit_count(&key->n), rng);
00977         if (ret != MP_OKAY)
00978             goto done;
00979 
00980         /* rndi = 1/rnd mod n */
00981         if (mp_invmod(&rnd, &key->n, &rndi) != MP_OKAY)
00982             ERROR_OUT(MP_INVMOD_E);
00983 
00984         /* rnd = rnd^e */
00985         if (mp_exptmod(&rnd, &key->e, &key->n, &rnd) != MP_OKAY)
00986             ERROR_OUT(MP_EXPTMOD_E);
00987 
00988         /* tmp = tmp*rnd mod n */
00989         if (mp_mulmod(&tmp, &rnd, &key->n, &tmp) != MP_OKAY)
00990             ERROR_OUT(MP_MULMOD_E);
00991     #endif /* WC_RSA_BLINGING */
00992 
00993     #ifdef RSA_LOW_MEM      /* half as much memory but twice as slow */
00994         if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY)
00995             ERROR_OUT(MP_EXPTMOD_E);
00996     #else
00997         /* Return 0 when cond is false and n when cond is true. */
00998         #define COND_N(cond, n)    ((0 - (cond)) & (n))
00999         /* If ret has an error value return it otherwise if r is OK then return
01000          * 0 otherwise return e.
01001          */
01002         #define RET_ERR(ret, r, e) \
01003             ((ret) | (COND_N((ret) == 0, COND_N((r) != MP_OKAY, (e)))))
01004 
01005         { /* tmpa/b scope */
01006         mp_int tmpa, tmpb;
01007         int r;
01008 
01009         if (mp_init(&tmpa) != MP_OKAY)
01010             ERROR_OUT(MP_INIT_E);
01011 
01012         if (mp_init(&tmpb) != MP_OKAY) {
01013             mp_clear(&tmpa);
01014             ERROR_OUT(MP_INIT_E);
01015         }
01016 
01017         /* tmpa = tmp^dP mod p */
01018         r = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa);
01019         ret = RET_ERR(ret, r, MP_EXPTMOD_E);
01020 
01021         /* tmpb = tmp^dQ mod q */
01022         r = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb);
01023         ret = RET_ERR(ret, r, MP_EXPTMOD_E);
01024 
01025         /* tmp = (tmpa - tmpb) * qInv (mod p) */
01026         r = mp_sub(&tmpa, &tmpb, &tmp);
01027         ret = RET_ERR(ret, r, MP_SUB_E);
01028 
01029         r = mp_mulmod(&tmp, &key->u, &key->p, &tmp);
01030         ret = RET_ERR(ret, r, MP_MULMOD_E);
01031 
01032         /* tmp = tmpb + q * tmp */
01033         r = mp_mul(&tmp, &key->q, &tmp);
01034         ret = RET_ERR(ret, r, MP_MUL_E);
01035 
01036         r = mp_add(&tmp, &tmpb, &tmp);
01037         ret = RET_ERR(ret, r, MP_ADD_E);
01038 
01039         mp_clear(&tmpa);
01040         mp_clear(&tmpb);
01041 
01042         if (ret != 0) {
01043             goto done;
01044         }
01045         #undef RET_ERR
01046         #undef COND_N
01047         } /* tmpa/b scope */
01048     #endif   /* RSA_LOW_MEM */
01049 
01050     #ifdef WC_RSA_BLINDING
01051         /* unblind */
01052         if (mp_mulmod(&tmp, &rndi, &key->n, &tmp) != MP_OKAY)
01053             ERROR_OUT(MP_MULMOD_E);
01054     #endif   /* WC_RSA_BLINDING */
01055 
01056         break;
01057     }
01058     case RSA_PUBLIC_ENCRYPT:
01059     case RSA_PUBLIC_DECRYPT:
01060         if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
01061             ERROR_OUT(MP_EXPTMOD_E);
01062         break;
01063     default:
01064         ERROR_OUT(RSA_WRONG_TYPE_E);
01065     }
01066 
01067     keyLen = wc_RsaEncryptSize(key);
01068     if (keyLen > *outLen) {
01069         ERROR_OUT(RSA_BUFFER_E);
01070     }
01071 
01072     len = mp_unsigned_bin_size(&tmp);
01073 
01074     /* pad front w/ zeros to match key length */
01075     while (len < keyLen) {
01076         *out++ = 0x00;
01077         len++;
01078     }
01079 
01080     *outLen = keyLen;
01081 
01082     /* convert */
01083     if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
01084         ERROR_OUT(MP_TO_E);
01085 
01086 done:
01087     mp_clear(&tmp);
01088 #ifdef WC_RSA_BLINDING
01089     if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
01090         mp_clear(&rndi);
01091         mp_clear(&rnd);
01092     }
01093 #endif
01094     return ret;
01095 }
01096 
01097 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
01098 static int wc_RsaFunctionAsync(const byte* in, word32 inLen, byte* out,
01099                           word32* outLen, int type, RsaKey* key, WC_RNG* rng)
01100 {
01101     int ret = 0;
01102 
01103     (void)rng;
01104 
01105 #ifdef WOLFSSL_ASYNC_CRYPT_TEST
01106     WC_ASYNC_TEST* testDev = &key->asyncDev.test;
01107     if (testDev->type == ASYNC_TEST_NONE) {
01108         testDev->type = ASYNC_TEST_RSA_FUNC;
01109         testDev->rsaFunc.in = in;
01110         testDev->rsaFunc.inSz = inLen;
01111         testDev->rsaFunc.out = out;
01112         testDev->rsaFunc.outSz = outLen;
01113         testDev->rsaFunc.type = type;
01114         testDev->rsaFunc.key = key;
01115         testDev->rsaFunc.rng = rng;
01116         return WC_PENDING_E;
01117     }
01118 #endif /* WOLFSSL_ASYNC_CRYPT_TEST */
01119 
01120     switch(type) {
01121     case RSA_PRIVATE_DECRYPT:
01122     case RSA_PRIVATE_ENCRYPT:
01123     #ifdef HAVE_CAVIUM
01124         ret = NitroxRsaExptMod(in, inLen,
01125                                key->d.raw.buf, key->d.raw.len,
01126                                key->n.raw.buf, key->n.raw.len,
01127                                out, outLen, key);
01128     #elif defined(HAVE_INTEL_QA)
01129         #ifdef RSA_LOW_MEM
01130             ret = IntelQaRsaPrivate(&key->asyncDev, in, inLen,
01131                                     &key->d.raw, &key->n.raw,
01132                                     out, outLen);
01133         #else
01134             ret = IntelQaRsaCrtPrivate(&key->asyncDev, in, inLen,
01135                                 &key->p.raw, &key->q.raw,
01136                                 &key->dP.raw, &key->dQ.raw,
01137                                 &key->u.raw,
01138                                 out, outLen);
01139         #endif
01140     #else /* WOLFSSL_ASYNC_CRYPT_TEST */
01141         ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
01142     #endif
01143         break;
01144 
01145     case RSA_PUBLIC_ENCRYPT:
01146     case RSA_PUBLIC_DECRYPT:
01147     #ifdef HAVE_CAVIUM
01148         ret = NitroxRsaExptMod(in, inLen,
01149                                key->e.raw.buf, key->e.raw.len,
01150                                key->n.raw.buf, key->n.raw.len,
01151                                out, outLen, key);
01152     #elif defined(HAVE_INTEL_QA)
01153         ret = IntelQaRsaPublic(&key->asyncDev, in, inLen,
01154                                &key->e.raw, &key->n.raw,
01155                                out, outLen);
01156     #else /* WOLFSSL_ASYNC_CRYPT_TEST */
01157         ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
01158     #endif
01159         break;
01160 
01161     default:
01162         ret = RSA_WRONG_TYPE_E;
01163     }
01164 
01165     return ret;
01166 }
01167 #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_RSA */
01168 
01169 int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
01170                           word32* outLen, int type, RsaKey* key, WC_RNG* rng)
01171 {
01172     int ret;
01173 
01174     if (key == NULL || in == NULL || inLen == 0 || out == NULL ||
01175             outLen == NULL || *outLen == 0 || type == RSA_TYPE_UNKNOWN) {
01176         return BAD_FUNC_ARG;
01177     }
01178 
01179 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
01180     if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
01181                                                         key->n.raw.len > 0) {
01182         ret = wc_RsaFunctionAsync(in, inLen, out, outLen, type, key, rng);
01183     }
01184     else
01185 #endif
01186     {
01187         ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
01188     }
01189 
01190     /* handle error */
01191     if (ret < 0 && ret != WC_PENDING_E) {
01192         if (ret == MP_EXPTMOD_E) {
01193             /* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */
01194             WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem");
01195         }
01196 
01197         key->state = RSA_STATE_NONE;
01198         wc_RsaCleanup(key);
01199     }
01200 
01201     return ret;
01202 }
01203 
01204 
01205 /* Internal Wrappers */
01206 /* Gives the option of choosing padding type
01207    in : input to be encrypted
01208    inLen: length of input buffer
01209    out: encrypted output
01210    outLen: length of encrypted output buffer
01211    key   : wolfSSL initialized RSA key struct
01212    rng   : wolfSSL initialized random number struct
01213    rsa_type  : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
01214         RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
01215    pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
01216    pad_type  : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD or
01217         WC_RSA_PSS_PAD
01218    hash  : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
01219    mgf   : type of mask generation function to use
01220    label : optional label
01221    labelSz : size of optional label buffer */
01222 static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
01223                             word32 outLen, RsaKey* key, int rsa_type,
01224                             byte pad_value, int pad_type,
01225                             enum wc_HashType hash, int mgf,
01226                             byte* label, word32 labelSz, WC_RNG* rng)
01227 {
01228     int ret, sz;
01229 
01230     if (in == NULL || inLen == 0 || out == NULL || key == NULL) {
01231         return BAD_FUNC_ARG;
01232     }
01233 
01234     sz = wc_RsaEncryptSize(key);
01235     if (sz > (int)outLen) {
01236         return RSA_BUFFER_E;
01237     }
01238 
01239     if (sz < RSA_MIN_PAD_SZ) {
01240         return WC_KEY_SIZE_E;
01241     }
01242 
01243     if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) {
01244         return RSA_BUFFER_E;
01245     }
01246 
01247     switch (key->state) {
01248     case RSA_STATE_NONE:
01249     case RSA_STATE_ENCRYPT_PAD:
01250         key->state = RSA_STATE_ENCRYPT_PAD;
01251 
01252     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
01253             defined(HAVE_CAVIUM)
01254         if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && key->n.raw.buf) {
01255             /* Async operations that include padding */
01256             if (rsa_type == RSA_PUBLIC_ENCRYPT &&
01257                                                 pad_value == RSA_BLOCK_TYPE_2) {
01258                 key->state = RSA_STATE_ENCRYPT_RES;
01259                 key->dataLen = key->n.raw.len;
01260                 return NitroxRsaPublicEncrypt(in, inLen, out, outLen, key);
01261             }
01262             else if (rsa_type == RSA_PRIVATE_ENCRYPT &&
01263                                                 pad_value == RSA_BLOCK_TYPE_1) {
01264                 key->state = RSA_STATE_ENCRYPT_RES;
01265                 key->dataLen = key->n.raw.len;
01266                 return NitroxRsaSSL_Sign(in, inLen, out, outLen, key);
01267             }
01268         }
01269     #endif
01270 
01271         ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash,
01272                                                 mgf, label, labelSz, key->heap);
01273         if (ret < 0) {
01274             break;
01275         }
01276 
01277         key->state = RSA_STATE_ENCRYPT_EXPTMOD;
01278         /* fall through */
01279 
01280     case RSA_STATE_ENCRYPT_EXPTMOD:
01281 
01282         key->dataLen = outLen;
01283         ret = wc_RsaFunction(out, sz, out, &key->dataLen, rsa_type, key, rng);
01284 
01285         if (ret >= 0 || ret == WC_PENDING_E) {
01286             key->state = RSA_STATE_ENCRYPT_RES;
01287         }
01288         if (ret < 0) {
01289             break;
01290         }
01291 
01292         /* fall through */
01293 
01294     case RSA_STATE_ENCRYPT_RES:
01295         ret = key->dataLen;
01296         break;
01297 
01298     default:
01299         ret = BAD_STATE_E;
01300         break;
01301     }
01302 
01303     /* if async pending then return and skip done cleanup below */
01304     if (ret == WC_PENDING_E) {
01305         return ret;
01306     }
01307 
01308     key->state = RSA_STATE_NONE;
01309     wc_RsaCleanup(key);
01310 
01311     return ret;
01312 }
01313 
01314 /* Gives the option of choosing padding type
01315    in : input to be decrypted
01316    inLen: length of input buffer
01317    out:  decrypted message
01318    outLen: length of decrypted message in bytes
01319    outPtr: optional inline output pointer (if provided doing inline)
01320    key   : wolfSSL initialized RSA key struct
01321    rsa_type  : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
01322         RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
01323    pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
01324    pad_type  : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD
01325         WC_RSA_PSS_PAD
01326    hash  : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
01327    mgf   : type of mask generation function to use
01328    label : optional label
01329    labelSz : size of optional label buffer */
01330 static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
01331                             word32 outLen, byte** outPtr, RsaKey* key,
01332                             int rsa_type, byte pad_value, int pad_type,
01333                             enum wc_HashType hash, int mgf,
01334                             byte* label, word32 labelSz, WC_RNG* rng)
01335 {
01336     int ret = RSA_WRONG_TYPE_E;
01337 
01338     if (in == NULL || inLen == 0 || out == NULL || key == NULL) {
01339         return BAD_FUNC_ARG;
01340     }
01341 
01342     switch (key->state) {
01343     case RSA_STATE_NONE:
01344     case RSA_STATE_DECRYPT_EXPTMOD:
01345         key->state = RSA_STATE_DECRYPT_EXPTMOD;
01346         key->dataLen = inLen;
01347 
01348     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
01349             defined(HAVE_CAVIUM)
01350         /* Async operations that include padding */
01351         if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
01352             if (rsa_type == RSA_PRIVATE_DECRYPT &&
01353                                                 pad_value == RSA_BLOCK_TYPE_2) {
01354                 key->state = RSA_STATE_DECRYPT_RES;
01355                 key->data = NULL;
01356                 if (outPtr)
01357                     *outPtr = in;
01358                 return NitroxRsaPrivateDecrypt(in, inLen, out, &key->dataLen, key);
01359             }
01360             else if (rsa_type == RSA_PUBLIC_DECRYPT &&
01361                                                 pad_value == RSA_BLOCK_TYPE_1) {
01362                 key->state = RSA_STATE_DECRYPT_RES;
01363                 key->data = NULL;
01364                 return NitroxRsaSSL_Verify(in, inLen, out, &key->dataLen, key);
01365             }
01366         }
01367     #endif
01368 
01369         /* verify the tmp ptr is NULL, otherwise indicates bad state */
01370         if (key->data != NULL) {
01371             ret = BAD_STATE_E;
01372             break;
01373         }
01374 
01375         /* if not doing this inline then allocate a buffer for it */
01376         if (outPtr == NULL) {
01377             key->data = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);
01378             key->dataIsAlloc = 1;
01379             if (key->data == NULL) {
01380                 ret = MEMORY_E;
01381                 break;
01382             }
01383             XMEMCPY(key->data, in, inLen);
01384         }
01385         else {
01386             key->data = out;
01387         }
01388         ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen, rsa_type,
01389                                                                       key, rng);
01390 
01391         if (ret >= 0 || ret == WC_PENDING_E) {
01392             key->state = RSA_STATE_DECRYPT_UNPAD;
01393         }
01394         if (ret < 0) {
01395             break;
01396         }
01397 
01398         /* fall through */
01399 
01400     case RSA_STATE_DECRYPT_UNPAD:
01401     {
01402         byte* pad = NULL;
01403         ret = wc_RsaUnPad_ex(key->data, key->dataLen, &pad, pad_value, pad_type,
01404                                           hash, mgf, label, labelSz, key->heap);
01405         if (ret > 0 && ret <= (int)outLen && pad != NULL) {
01406             /* only copy output if not inline */
01407             if (outPtr == NULL) {
01408                 XMEMCPY(out, pad, ret);
01409             }
01410             else {
01411                 *outPtr = pad;
01412             }
01413         }
01414         else if (ret >= 0) {
01415             ret = RSA_BUFFER_E;
01416         }
01417         if (ret < 0) {
01418             break;
01419         }
01420 
01421         key->state = RSA_STATE_DECRYPT_RES;
01422         /* fall through */
01423     }
01424     case RSA_STATE_DECRYPT_RES:
01425     #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
01426             defined(HAVE_CAVIUM)
01427         if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
01428             /* return event ret */
01429             ret = key->asyncDev.event.ret;
01430             if (ret == 0) {
01431                 /* convert result */
01432                 byte* dataLen = (byte*)&key->dataLen;
01433                 ret = (dataLen[0] << 8) | (dataLen[1]);
01434             }
01435         }
01436     #endif
01437         break;
01438 
01439     default:
01440         ret = BAD_STATE_E;
01441         break;
01442     }
01443 
01444     /* if async pending then return and skip done cleanup below */
01445     if (ret == WC_PENDING_E) {
01446         return ret;
01447     }
01448 
01449     key->state = RSA_STATE_NONE;
01450     wc_RsaCleanup(key);
01451 
01452     return ret;
01453 }
01454 
01455 
01456 /* Public RSA Functions */
01457 int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
01458                                                      RsaKey* key, WC_RNG* rng)
01459 {
01460     return RsaPublicEncryptEx(in, inLen, out, outLen, key,
01461         RSA_PUBLIC_ENCRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
01462         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
01463 }
01464 
01465 
01466 #ifndef WC_NO_RSA_OAEP
01467 int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,
01468                     word32 outLen, RsaKey* key, WC_RNG* rng, int type,
01469                     enum wc_HashType hash, int mgf, byte* label,
01470                     word32 labelSz)
01471 {
01472     return RsaPublicEncryptEx(in, inLen, out, outLen, key, RSA_PUBLIC_ENCRYPT,
01473         RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, rng);
01474 }
01475 #endif /* WC_NO_RSA_OAEP */
01476 
01477 
01478 int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
01479 {
01480     WC_RNG* rng = NULL;
01481 #ifdef WC_RSA_BLINDING
01482     rng = key->rng;
01483 #endif
01484     return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
01485         RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
01486         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
01487 }
01488 
01489 
01490 #ifndef WC_NO_RSA_OAEP
01491 int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out,
01492                                   RsaKey* key, int type, enum wc_HashType hash,
01493                                   int mgf, byte* label, word32 labelSz)
01494 {
01495     WC_RNG* rng = NULL;
01496 #ifdef WC_RSA_BLINDING
01497     rng = key->rng;
01498 #endif
01499     return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
01500         RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash,
01501         mgf, label, labelSz, rng);
01502 }
01503 #endif /* WC_NO_RSA_OAEP */
01504 
01505 
01506 int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
01507                                                  word32 outLen, RsaKey* key)
01508 {
01509     WC_RNG* rng = NULL;
01510 #ifdef WC_RSA_BLINDING
01511     rng = key->rng;
01512 #endif
01513     return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
01514         RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
01515         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
01516 }
01517 
01518 
01519 #ifndef WC_NO_RSA_OAEP
01520 int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out,
01521                             word32 outLen, RsaKey* key, int type,
01522                             enum wc_HashType hash, int mgf, byte* label,
01523                             word32 labelSz)
01524 {
01525     WC_RNG* rng = NULL;
01526 #ifdef WC_RSA_BLINDING
01527     rng = key->rng;
01528 #endif
01529     return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
01530         RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label,
01531         labelSz, rng);
01532 }
01533 #endif /* WC_NO_RSA_OAEP */
01534 
01535 
01536 int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
01537 {
01538     WC_RNG* rng = NULL;
01539 #ifdef WC_RSA_BLINDING
01540     rng = key->rng;
01541 #endif
01542     return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
01543         RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
01544         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
01545 }
01546 
01547 int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
01548                                                                  RsaKey* key)
01549 {
01550     WC_RNG* rng = NULL;
01551 #ifdef WC_RSA_BLINDING
01552     rng = key->rng;
01553 #endif
01554     return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
01555         RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
01556         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
01557 }
01558 
01559 #ifdef WC_RSA_PSS
01560 int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out,
01561                            enum wc_HashType hash, int mgf, RsaKey* key)
01562 {
01563     WC_RNG* rng = NULL;
01564 #ifdef WC_RSA_BLINDING
01565     rng = key->rng;
01566 #endif
01567     return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
01568         RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD,
01569         hash, mgf, NULL, 0, rng);
01570 }
01571 #endif
01572 
01573 int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
01574                                                    RsaKey* key, WC_RNG* rng)
01575 {
01576     return RsaPublicEncryptEx(in, inLen, out, outLen, key,
01577         RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
01578         WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
01579 }
01580 
01581 
01582 int wc_RsaEncryptSize(RsaKey* key)
01583 {
01584     return mp_unsigned_bin_size(&key->n);
01585 }
01586 
01587 
01588 /* flatten RsaKey structure into individual elements (e, n) */
01589 int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,
01590                                                                    word32* nSz)
01591 {
01592     int sz, ret;
01593 
01594     if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL) {
01595         return BAD_FUNC_ARG;
01596     }
01597 
01598     sz = mp_unsigned_bin_size(&key->e);
01599     if ((word32)sz > *eSz)
01600         return RSA_BUFFER_E;
01601     ret = mp_to_unsigned_bin(&key->e, e);
01602     if (ret != MP_OKAY)
01603         return ret;
01604     *eSz = (word32)sz;
01605 
01606     sz = wc_RsaEncryptSize(key);
01607     if ((word32)sz > *nSz)
01608         return RSA_BUFFER_E;
01609     ret = mp_to_unsigned_bin(&key->n, n);
01610     if (ret != MP_OKAY)
01611         return ret;
01612     *nSz = (word32)sz;
01613 
01614     return 0;
01615 }
01616 
01617 #ifdef WOLFSSL_KEY_GEN
01618 /* Make an RSA key for size bits, with e specified, 65537 is a good e */
01619 int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
01620 {
01621     mp_int p, q, tmp1, tmp2, tmp3;
01622     int    err;
01623 
01624     if (key == NULL || rng == NULL)
01625         return BAD_FUNC_ARG;
01626 
01627     if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
01628         return BAD_FUNC_ARG;
01629 
01630     if (e < 3 || (e & 1) == 0)
01631         return BAD_FUNC_ARG;
01632 
01633 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
01634     if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
01635     #ifdef HAVE_CAVIUM
01636         /* TODO: Not implemented */
01637     #elif defined(HAVE_INTEL_QA)
01638         /* TODO: Not implemented */
01639     #else
01640         WC_ASYNC_TEST* testDev = &key->asyncDev.test;
01641         if (testDev->type == ASYNC_TEST_NONE) {
01642             testDev->type = ASYNC_TEST_RSA_MAKE;
01643             testDev->rsaMake.rng = rng;
01644             testDev->rsaMake.key = key;
01645             testDev->rsaMake.size = size;
01646             testDev->rsaMake.e = e;
01647             return WC_PENDING_E;
01648         }
01649     #endif
01650     }
01651 #endif
01652 
01653     if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
01654         return err;
01655 
01656     err = mp_set_int(&tmp3, e);
01657 
01658     /* make p */
01659     if (err == MP_OKAY) {
01660         do {
01661             err = mp_rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */
01662 
01663             if (err == MP_OKAY)
01664                 err = mp_sub_d(&p, 1, &tmp1);  /* tmp1 = p-1 */
01665 
01666             if (err == MP_OKAY)
01667                 err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(p-1, e) */
01668         } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divides p-1 */
01669     }
01670 
01671     /* make q */
01672     if (err == MP_OKAY) {
01673         do {
01674             err = mp_rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */
01675 
01676             if (err == MP_OKAY)
01677                 err = mp_sub_d(&q, 1, &tmp1);  /* tmp1 = q-1 */
01678 
01679             if (err == MP_OKAY)
01680                 err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(q-1, e) */
01681         } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divides q-1 */
01682     }
01683 
01684     if (err == MP_OKAY)
01685         err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);
01686 
01687     if (err == MP_OKAY)
01688         err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
01689 
01690     if (err == MP_OKAY)
01691         err = mp_sub_d(&p, 1, &tmp2);  /* tmp2 = p-1 */
01692 
01693     if (err == MP_OKAY)
01694         err = mp_lcm(&tmp1, &tmp2, &tmp1);  /* tmp1 = lcm(p-1, q-1),last loop */
01695 
01696     /* make key */
01697     if (err == MP_OKAY)
01698         err = mp_set_int(&key->e, (mp_digit)e);  /* key->e = e */
01699 
01700     if (err == MP_OKAY)                /* key->d = 1/e mod lcm(p-1, q-1) */
01701         err = mp_invmod(&key->e, &tmp1, &key->d);
01702 
01703     if (err == MP_OKAY)
01704         err = mp_mul(&p, &q, &key->n);  /* key->n = pq */
01705 
01706     if (err == MP_OKAY)
01707         err = mp_sub_d(&p, 1, &tmp1);
01708 
01709     if (err == MP_OKAY)
01710         err = mp_sub_d(&q, 1, &tmp2);
01711 
01712     if (err == MP_OKAY)
01713         err = mp_mod(&key->d, &tmp1, &key->dP);
01714 
01715     if (err == MP_OKAY)
01716         err = mp_mod(&key->d, &tmp2, &key->dQ);
01717 
01718     if (err == MP_OKAY)
01719         err = mp_invmod(&q, &p, &key->u);
01720 
01721     if (err == MP_OKAY)
01722         err = mp_copy(&p, &key->p);
01723 
01724     if (err == MP_OKAY)
01725         err = mp_copy(&q, &key->q);
01726 
01727     if (err == MP_OKAY)
01728         key->type = RSA_PRIVATE;
01729 
01730     mp_clear(&tmp3);
01731     mp_clear(&tmp2);
01732     mp_clear(&tmp1);
01733     mp_clear(&q);
01734     mp_clear(&p);
01735 
01736     if (err != MP_OKAY) {
01737         wc_FreeRsaKey(key);
01738         return err;
01739     }
01740 
01741     return 0;
01742 }
01743 #endif /* WOLFSSL_KEY_GEN */
01744 
01745 
01746 #ifdef WC_RSA_BLINDING
01747 
01748 int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
01749 {
01750     if (key == NULL)
01751         return BAD_FUNC_ARG;
01752 
01753     key->rng = rng;
01754 
01755     return 0;
01756 }
01757 
01758 #endif /* WC_RSA_BLINDING */
01759 
01760 
01761 #undef ERROR_OUT
01762 
01763 #endif /* HAVE_FIPS */
01764 #endif /* NO_RSA */
01765