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