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