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