Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of wolfSSL by
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
Generated on Tue Jul 12 2022 23:30:59 by
1.7.2
