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 CyaSSL by
rsa.c
00001 /* rsa.c 00002 * 00003 * Copyright (C) 2006-2014 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL 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 * CyaSSL 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-1301, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <cyassl/ctaocrypt/settings.h> 00028 00029 #ifndef NO_RSA 00030 00031 #ifdef HAVE_FIPS 00032 /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ 00033 #define FIPS_NO_WRAPPERS 00034 #endif 00035 00036 #include <cyassl/ctaocrypt/rsa.h> 00037 #include <cyassl/ctaocrypt/random.h> 00038 #include <cyassl/ctaocrypt/error-crypt.h> 00039 #include <cyassl/ctaocrypt/logging.h> 00040 00041 #ifdef SHOW_GEN 00042 #ifdef FREESCALE_MQX 00043 #include <fio.h> 00044 #else 00045 #include <stdio.h> 00046 #endif 00047 #endif 00048 00049 #ifdef HAVE_CAVIUM 00050 static int InitCaviumRsaKey(RsaKey* key, void* heap); 00051 static int FreeCaviumRsaKey(RsaKey* key); 00052 static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out, 00053 word32 outLen, RsaKey* key); 00054 static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, 00055 word32 outLen, RsaKey* key); 00056 static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out, 00057 word32 outLen, RsaKey* key); 00058 static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out, 00059 word32 outLen, RsaKey* key); 00060 #endif 00061 00062 enum { 00063 RSA_PUBLIC_ENCRYPT = 0, 00064 RSA_PUBLIC_DECRYPT = 1, 00065 RSA_PRIVATE_ENCRYPT = 2, 00066 RSA_PRIVATE_DECRYPT = 3, 00067 00068 RSA_BLOCK_TYPE_1 = 1, 00069 RSA_BLOCK_TYPE_2 = 2, 00070 00071 RSA_MIN_SIZE = 512, 00072 RSA_MAX_SIZE = 4096, 00073 00074 RSA_MIN_PAD_SZ = 11 /* seperator + 0 + pad value + 8 pads */ 00075 }; 00076 00077 00078 int InitRsaKey(RsaKey* key, void* heap) 00079 { 00080 #ifdef HAVE_CAVIUM 00081 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) 00082 return InitCaviumRsaKey(key, heap); 00083 #endif 00084 00085 key->type = -1; /* haven't decided yet */ 00086 key->heap = heap; 00087 00088 /* TomsFastMath doesn't use memory allocation */ 00089 #ifndef USE_FAST_MATH 00090 key->n.dp = key->e.dp = 0; /* public alloc parts */ 00091 00092 key->d.dp = key->p.dp = 0; /* private alloc parts */ 00093 key->q.dp = key->dP.dp = 0; 00094 key->u.dp = key->dQ.dp = 0; 00095 #endif 00096 00097 return 0; 00098 } 00099 00100 00101 int FreeRsaKey(RsaKey* key) 00102 { 00103 (void)key; 00104 00105 #ifdef HAVE_CAVIUM 00106 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) 00107 return FreeCaviumRsaKey(key); 00108 #endif 00109 00110 /* TomsFastMath doesn't use memory allocation */ 00111 #ifndef USE_FAST_MATH 00112 if (key->type == RSA_PRIVATE) { 00113 mp_clear(&key->u); 00114 mp_clear(&key->dQ); 00115 mp_clear(&key->dP); 00116 mp_clear(&key->q); 00117 mp_clear(&key->p); 00118 mp_clear(&key->d); 00119 } 00120 mp_clear(&key->e); 00121 mp_clear(&key->n); 00122 #endif 00123 00124 return 0; 00125 } 00126 00127 static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, 00128 word32 pkcsBlockLen, byte padValue, RNG* rng) 00129 { 00130 if (inputLen == 0) 00131 return 0; 00132 00133 pkcsBlock[0] = 0x0; /* set first byte to zero and advance */ 00134 pkcsBlock++; pkcsBlockLen--; 00135 pkcsBlock[0] = padValue; /* insert padValue */ 00136 00137 if (padValue == RSA_BLOCK_TYPE_1) 00138 /* pad with 0xff bytes */ 00139 XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2); 00140 else { 00141 /* pad with non-zero random bytes */ 00142 word32 padLen = pkcsBlockLen - inputLen - 1, i; 00143 int ret = RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); 00144 00145 if (ret != 0) 00146 return ret; 00147 00148 /* remove zeros */ 00149 for (i = 1; i < padLen; i++) 00150 if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01; 00151 } 00152 00153 pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */ 00154 XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen); 00155 00156 return 0; 00157 } 00158 00159 00160 static word32 RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, 00161 byte **output, byte padValue) 00162 { 00163 word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0, 00164 invalid = 0, 00165 i = 1, 00166 outputLen; 00167 00168 if (pkcsBlock[0] != 0x0) /* skip past zero */ 00169 invalid = 1; 00170 pkcsBlock++; pkcsBlockLen--; 00171 00172 /* Require block type padValue */ 00173 invalid = (pkcsBlock[0] != padValue) || invalid; 00174 00175 /* skip past the padding until we find the separator */ 00176 while (i<pkcsBlockLen && pkcsBlock[i++]) { /* null body */ 00177 } 00178 if(!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) { 00179 CYASSL_MSG("RsaUnPad error, bad formatting"); 00180 return 0; 00181 } 00182 00183 outputLen = pkcsBlockLen - i; 00184 invalid = (outputLen > maxOutputLen) || invalid; 00185 00186 if (invalid) { 00187 CYASSL_MSG("RsaUnPad error, bad formatting"); 00188 return 0; 00189 } 00190 00191 *output = (byte *)(pkcsBlock + i); 00192 return outputLen; 00193 } 00194 00195 00196 static int RsaFunction(const byte* in, word32 inLen, byte* out, word32* outLen, 00197 int type, RsaKey* key) 00198 { 00199 #define ERROR_OUT(x) { ret = x; goto done;} 00200 00201 mp_int tmp; 00202 int ret = 0; 00203 word32 keyLen, len; 00204 00205 if (mp_init(&tmp) != MP_OKAY) 00206 return MP_INIT_E; 00207 00208 if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY) 00209 ERROR_OUT(MP_READ_E); 00210 00211 if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) { 00212 #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */ 00213 if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY) 00214 ERROR_OUT(MP_EXPTMOD_E); 00215 #else 00216 #define INNER_ERROR_OUT(x) { ret = x; goto inner_done; } 00217 00218 mp_int tmpa, tmpb; 00219 00220 if (mp_init(&tmpa) != MP_OKAY) 00221 ERROR_OUT(MP_INIT_E); 00222 00223 if (mp_init(&tmpb) != MP_OKAY) { 00224 mp_clear(&tmpa); 00225 ERROR_OUT(MP_INIT_E); 00226 } 00227 00228 /* tmpa = tmp^dP mod p */ 00229 if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY) 00230 INNER_ERROR_OUT(MP_EXPTMOD_E); 00231 00232 /* tmpb = tmp^dQ mod q */ 00233 if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY) 00234 INNER_ERROR_OUT(MP_EXPTMOD_E); 00235 00236 /* tmp = (tmpa - tmpb) * qInv (mod p) */ 00237 if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY) 00238 INNER_ERROR_OUT(MP_SUB_E); 00239 00240 if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY) 00241 INNER_ERROR_OUT(MP_MULMOD_E); 00242 00243 /* tmp = tmpb + q * tmp */ 00244 if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY) 00245 INNER_ERROR_OUT(MP_MUL_E); 00246 00247 if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY) 00248 INNER_ERROR_OUT(MP_ADD_E); 00249 00250 inner_done: 00251 mp_clear(&tmpa); 00252 mp_clear(&tmpb); 00253 00254 if (ret != 0) return ret; 00255 00256 #endif /* RSA_LOW_MEM */ 00257 } 00258 else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) { 00259 if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY) 00260 ERROR_OUT(MP_EXPTMOD_E); 00261 } 00262 else 00263 ERROR_OUT(RSA_WRONG_TYPE_E); 00264 00265 keyLen = mp_unsigned_bin_size(&key->n); 00266 if (keyLen > *outLen) 00267 ERROR_OUT(RSA_BUFFER_E); 00268 00269 len = mp_unsigned_bin_size(&tmp); 00270 00271 /* pad front w/ zeros to match key length */ 00272 while (len < keyLen) { 00273 *out++ = 0x00; 00274 len++; 00275 } 00276 00277 *outLen = keyLen; 00278 00279 /* convert */ 00280 if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY) 00281 ERROR_OUT(MP_TO_E); 00282 00283 done: 00284 mp_clear(&tmp); 00285 return ret; 00286 } 00287 00288 00289 int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, 00290 RsaKey* key, RNG* rng) 00291 { 00292 int sz, ret; 00293 00294 #ifdef HAVE_CAVIUM 00295 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) 00296 return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key); 00297 #endif 00298 00299 sz = mp_unsigned_bin_size(&key->n); 00300 if (sz > (int)outLen) 00301 return RSA_BUFFER_E; 00302 00303 if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) 00304 return RSA_BUFFER_E; 00305 00306 ret = RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng); 00307 if (ret != 0) 00308 return ret; 00309 00310 if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PUBLIC_ENCRYPT, key)) < 0) 00311 sz = ret; 00312 00313 return sz; 00314 } 00315 00316 00317 int RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key) 00318 { 00319 int plainLen, ret; 00320 00321 #ifdef HAVE_CAVIUM 00322 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) { 00323 ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key); 00324 if (ret > 0) 00325 *out = in; 00326 return ret; 00327 } 00328 #endif 00329 00330 if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key)) 00331 < 0) { 00332 return ret; 00333 } 00334 00335 plainLen = RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_2); 00336 00337 return plainLen; 00338 } 00339 00340 00341 int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen, 00342 RsaKey* key) 00343 { 00344 int plainLen, ret; 00345 byte* tmp; 00346 byte* pad = 0; 00347 00348 #ifdef HAVE_CAVIUM 00349 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) 00350 return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key); 00351 #endif 00352 00353 tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA); 00354 if (tmp == NULL) { 00355 return MEMORY_E; 00356 } 00357 00358 XMEMCPY(tmp, in, inLen); 00359 00360 if ((ret = plainLen = RsaPrivateDecryptInline(tmp, inLen, &pad, key)) 00361 < 0) { 00362 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); 00363 return ret; 00364 } 00365 if (plainLen > (int)outLen) 00366 plainLen = BAD_FUNC_ARG; 00367 else 00368 XMEMCPY(out, pad, plainLen); 00369 XMEMSET(tmp, 0x00, inLen); 00370 00371 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); 00372 return plainLen; 00373 } 00374 00375 00376 /* for Rsa Verify */ 00377 int RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) 00378 { 00379 int plainLen, ret; 00380 00381 #ifdef HAVE_CAVIUM 00382 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) { 00383 ret = CaviumRsaSSL_Verify(in, inLen, in, inLen, key); 00384 if (ret > 0) 00385 *out = in; 00386 return ret; 00387 } 00388 #endif 00389 00390 if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key)) 00391 < 0) { 00392 return ret; 00393 } 00394 00395 plainLen = RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1); 00396 00397 return plainLen; 00398 } 00399 00400 00401 int RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, 00402 RsaKey* key) 00403 { 00404 int plainLen, ret; 00405 byte* tmp; 00406 byte* pad = 0; 00407 00408 #ifdef HAVE_CAVIUM 00409 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) 00410 return CaviumRsaSSL_Verify(in, inLen, out, outLen, key); 00411 #endif 00412 00413 tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA); 00414 if (tmp == NULL) { 00415 return MEMORY_E; 00416 } 00417 00418 XMEMCPY(tmp, in, inLen); 00419 00420 if ((ret = plainLen = RsaSSL_VerifyInline(tmp, inLen, &pad, key)) 00421 < 0) { 00422 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); 00423 return ret; 00424 } 00425 00426 if (plainLen > (int)outLen) 00427 plainLen = BAD_FUNC_ARG; 00428 else 00429 XMEMCPY(out, pad, plainLen); 00430 XMEMSET(tmp, 0x00, inLen); 00431 00432 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); 00433 return plainLen; 00434 } 00435 00436 00437 /* for Rsa Sign */ 00438 int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, 00439 RsaKey* key, RNG* rng) 00440 { 00441 int sz, ret; 00442 00443 #ifdef HAVE_CAVIUM 00444 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) 00445 return CaviumRsaSSL_Sign(in, inLen, out, outLen, key); 00446 #endif 00447 00448 sz = mp_unsigned_bin_size(&key->n); 00449 if (sz > (int)outLen) 00450 return RSA_BUFFER_E; 00451 00452 if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) 00453 return RSA_BUFFER_E; 00454 00455 ret = RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng); 00456 if (ret != 0) 00457 return ret; 00458 00459 if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PRIVATE_ENCRYPT,key)) < 0) 00460 sz = ret; 00461 00462 return sz; 00463 } 00464 00465 00466 int RsaEncryptSize(RsaKey* key) 00467 { 00468 #ifdef HAVE_CAVIUM 00469 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) 00470 return key->c_nSz; 00471 #endif 00472 return mp_unsigned_bin_size(&key->n); 00473 } 00474 00475 00476 #ifdef CYASSL_KEY_GEN 00477 00478 static const int USE_BBS = 1; 00479 00480 static int rand_prime(mp_int* N, int len, RNG* rng, void* heap) 00481 { 00482 int err, res, type; 00483 byte* buf; 00484 00485 (void)heap; 00486 if (N == NULL || rng == NULL) 00487 return BAD_FUNC_ARG; 00488 00489 /* get type */ 00490 if (len < 0) { 00491 type = USE_BBS; 00492 len = -len; 00493 } else { 00494 type = 0; 00495 } 00496 00497 /* allow sizes between 2 and 512 bytes for a prime size */ 00498 if (len < 2 || len > 512) { 00499 return BAD_FUNC_ARG; 00500 } 00501 00502 /* allocate buffer to work with */ 00503 buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA); 00504 if (buf == NULL) { 00505 return MEMORY_E; 00506 } 00507 XMEMSET(buf, 0, len); 00508 00509 do { 00510 #ifdef SHOW_GEN 00511 printf("."); 00512 fflush(stdout); 00513 #endif 00514 /* generate value */ 00515 err = RNG_GenerateBlock(rng, buf, len); 00516 if (err != 0) { 00517 XFREE(buf, heap, DYNAMIC_TYPE_RSA); 00518 return err; 00519 } 00520 00521 /* munge bits */ 00522 buf[0] |= 0x80 | 0x40; 00523 buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); 00524 00525 /* load value */ 00526 if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) { 00527 XFREE(buf, heap, DYNAMIC_TYPE_RSA); 00528 return err; 00529 } 00530 00531 /* test */ 00532 if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) { 00533 XFREE(buf, heap, DYNAMIC_TYPE_RSA); 00534 return err; 00535 } 00536 } while (res == MP_NO); 00537 00538 #ifdef LTC_CLEAN_STACK 00539 XMEMSET(buf, 0, len); 00540 #endif 00541 00542 XFREE(buf, heap, DYNAMIC_TYPE_RSA); 00543 return 0; 00544 } 00545 00546 00547 /* Make an RSA key for size bits, with e specified, 65537 is a good e */ 00548 int MakeRsaKey(RsaKey* key, int size, long e, RNG* rng) 00549 { 00550 mp_int p, q, tmp1, tmp2, tmp3; 00551 int err; 00552 00553 if (key == NULL || rng == NULL) 00554 return BAD_FUNC_ARG; 00555 00556 if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE) 00557 return BAD_FUNC_ARG; 00558 00559 if (e < 3 || (e & 1) == 0) 00560 return BAD_FUNC_ARG; 00561 00562 if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY) 00563 return err; 00564 00565 err = mp_set_int(&tmp3, e); 00566 00567 /* make p */ 00568 if (err == MP_OKAY) { 00569 do { 00570 err = rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */ 00571 00572 if (err == MP_OKAY) 00573 err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */ 00574 00575 if (err == MP_OKAY) 00576 err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(p-1, e) */ 00577 } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes p-1 */ 00578 } 00579 00580 /* make q */ 00581 if (err == MP_OKAY) { 00582 do { 00583 err = rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */ 00584 00585 if (err == MP_OKAY) 00586 err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q-1 */ 00587 00588 if (err == MP_OKAY) 00589 err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(q-1, e) */ 00590 } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes q-1 */ 00591 } 00592 00593 if (err == MP_OKAY) 00594 err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL); 00595 00596 if (err == MP_OKAY) 00597 err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL); 00598 00599 if (err == MP_OKAY) 00600 err = mp_sub_d(&p, 1, &tmp2); /* tmp2 = p-1 */ 00601 00602 if (err == MP_OKAY) 00603 err = mp_lcm(&tmp1, &tmp2, &tmp1); /* tmp1 = lcm(p-1, q-1),last loop */ 00604 00605 /* make key */ 00606 if (err == MP_OKAY) 00607 err = mp_set_int(&key->e, e); /* key->e = e */ 00608 00609 if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */ 00610 err = mp_invmod(&key->e, &tmp1, &key->d); 00611 00612 if (err == MP_OKAY) 00613 err = mp_mul(&p, &q, &key->n); /* key->n = pq */ 00614 00615 if (err == MP_OKAY) 00616 err = mp_sub_d(&p, 1, &tmp1); 00617 00618 if (err == MP_OKAY) 00619 err = mp_sub_d(&q, 1, &tmp2); 00620 00621 if (err == MP_OKAY) 00622 err = mp_mod(&key->d, &tmp1, &key->dP); 00623 00624 if (err == MP_OKAY) 00625 err = mp_mod(&key->d, &tmp2, &key->dQ); 00626 00627 if (err == MP_OKAY) 00628 err = mp_invmod(&q, &p, &key->u); 00629 00630 if (err == MP_OKAY) 00631 err = mp_copy(&p, &key->p); 00632 00633 if (err == MP_OKAY) 00634 err = mp_copy(&q, &key->q); 00635 00636 if (err == MP_OKAY) 00637 key->type = RSA_PRIVATE; 00638 00639 mp_clear(&tmp3); 00640 mp_clear(&tmp2); 00641 mp_clear(&tmp1); 00642 mp_clear(&q); 00643 mp_clear(&p); 00644 00645 if (err != MP_OKAY) { 00646 FreeRsaKey(key); 00647 return err; 00648 } 00649 00650 return 0; 00651 } 00652 00653 00654 #endif /* CYASSL_KEY_GEN */ 00655 00656 00657 #ifdef HAVE_CAVIUM 00658 00659 #include <cyassl/ctaocrypt/logging.h> 00660 #include "cavium_common.h" 00661 00662 /* Initiliaze RSA for use with Nitrox device */ 00663 int RsaInitCavium(RsaKey* rsa, int devId) 00664 { 00665 if (rsa == NULL) 00666 return -1; 00667 00668 if (CspAllocContext(CONTEXT_SSL, &rsa->contextHandle, devId) != 0) 00669 return -1; 00670 00671 rsa->devId = devId; 00672 rsa->magic = CYASSL_RSA_CAVIUM_MAGIC; 00673 00674 return 0; 00675 } 00676 00677 00678 /* Free RSA from use with Nitrox device */ 00679 void RsaFreeCavium(RsaKey* rsa) 00680 { 00681 if (rsa == NULL) 00682 return; 00683 00684 CspFreeContext(CONTEXT_SSL, rsa->contextHandle, rsa->devId); 00685 rsa->magic = 0; 00686 } 00687 00688 00689 /* Initialize cavium RSA key */ 00690 static int InitCaviumRsaKey(RsaKey* key, void* heap) 00691 { 00692 if (key == NULL) 00693 return BAD_FUNC_ARG; 00694 00695 key->heap = heap; 00696 key->type = -1; /* don't know yet */ 00697 00698 key->c_n = NULL; 00699 key->c_e = NULL; 00700 key->c_d = NULL; 00701 key->c_p = NULL; 00702 key->c_q = NULL; 00703 key->c_dP = NULL; 00704 key->c_dQ = NULL; 00705 key->c_u = NULL; 00706 00707 key->c_nSz = 0; 00708 key->c_eSz = 0; 00709 key->c_dSz = 0; 00710 key->c_pSz = 0; 00711 key->c_qSz = 0; 00712 key->c_dP_Sz = 0; 00713 key->c_dQ_Sz = 0; 00714 key->c_uSz = 0; 00715 00716 return 0; 00717 } 00718 00719 00720 /* Free cavium RSA key */ 00721 static int FreeCaviumRsaKey(RsaKey* key) 00722 { 00723 if (key == NULL) 00724 return BAD_FUNC_ARG; 00725 00726 XFREE(key->c_n, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); 00727 XFREE(key->c_e, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); 00728 XFREE(key->c_d, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); 00729 XFREE(key->c_p, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); 00730 XFREE(key->c_q, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); 00731 XFREE(key->c_dP, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); 00732 XFREE(key->c_dQ, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); 00733 XFREE(key->c_u, key->heap, DYNAMIC_TYPE_CAVIUM_TMP); 00734 00735 return InitCaviumRsaKey(key, key->heap); /* reset pointers */ 00736 } 00737 00738 00739 static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out, 00740 word32 outLen, RsaKey* key) 00741 { 00742 word32 requestId; 00743 word32 ret; 00744 00745 if (key == NULL || in == NULL || out == NULL || outLen < (word32)key->c_nSz) 00746 return -1; 00747 00748 ret = CspPkcs1v15Enc(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_eSz, 00749 (word16)inLen, key->c_n, key->c_e, (byte*)in, out, 00750 &requestId, key->devId); 00751 if (ret != 0) { 00752 CYASSL_MSG("Cavium Enc BT2 failed"); 00753 return -1; 00754 } 00755 return key->c_nSz; 00756 } 00757 00758 00759 static INLINE void ato16(const byte* c, word16* u16) 00760 { 00761 *u16 = (c[0] << 8) | (c[1]); 00762 } 00763 00764 00765 static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, 00766 word32 outLen, RsaKey* key) 00767 { 00768 word32 requestId; 00769 word32 ret; 00770 word16 outSz = (word16)outLen; 00771 00772 if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz) 00773 return -1; 00774 00775 ret = CspPkcs1v15CrtDec(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_q, 00776 key->c_dQ, key->c_p, key->c_dP, key->c_u, 00777 (byte*)in, &outSz, out, &requestId, key->devId); 00778 if (ret != 0) { 00779 CYASSL_MSG("Cavium CRT Dec BT2 failed"); 00780 return -1; 00781 } 00782 ato16((const byte*)&outSz, &outSz); 00783 00784 return outSz; 00785 } 00786 00787 00788 static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out, 00789 word32 outLen, RsaKey* key) 00790 { 00791 word32 requestId; 00792 word32 ret; 00793 00794 if (key == NULL || in == NULL || out == NULL || inLen == 0 || outLen < 00795 (word32)key->c_nSz) 00796 return -1; 00797 00798 ret = CspPkcs1v15CrtEnc(CAVIUM_BLOCKING, BT1, key->c_nSz, (word16)inLen, 00799 key->c_q, key->c_dQ, key->c_p, key->c_dP, key->c_u, 00800 (byte*)in, out, &requestId, key->devId); 00801 if (ret != 0) { 00802 CYASSL_MSG("Cavium CRT Enc BT1 failed"); 00803 return -1; 00804 } 00805 return key->c_nSz; 00806 } 00807 00808 00809 static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out, 00810 word32 outLen, RsaKey* key) 00811 { 00812 word32 requestId; 00813 word32 ret; 00814 word16 outSz = (word16)outLen; 00815 00816 if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz) 00817 return -1; 00818 00819 ret = CspPkcs1v15Dec(CAVIUM_BLOCKING, BT1, key->c_nSz, key->c_eSz, 00820 key->c_n, key->c_e, (byte*)in, &outSz, out, 00821 &requestId, key->devId); 00822 if (ret != 0) { 00823 CYASSL_MSG("Cavium Dec BT1 failed"); 00824 return -1; 00825 } 00826 outSz = ntohs(outSz); 00827 00828 return outSz; 00829 } 00830 00831 00832 #endif /* HAVE_CAVIUM */ 00833 00834 #endif /* NO_RSA */ 00835
Generated on Tue Jul 12 2022 21:40:05 by
1.7.2
