1  /* rsa.c


2  *


3  * Copyright (C) 20062015 wolfSSL Inc.


4  *


5  * This file is part of wolfSSL. (formerly known as CyaSSL)


6  *


7  * wolfSSL is free software; you can redistribute it and/or modify


8  * it under the terms of the GNU General Public License as published by


9  * the Free Software Foundation; either version 2 of the License, or


10  * (at your option) any later version.


11  *


12  * wolfSSL is distributed in the hope that it will be useful,


13  * but WITHOUT ANY WARRANTY; without even the implied warranty of


14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the


15  * GNU General Public License for more details.


16  *


17  * You should have received a copy of the GNU General Public License


18  * along with this program; if not, write to the Free Software


19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 021101301, USA


20  */


21 


22  #ifdef HAVE_CONFIG_H


23  #include <config.h>


24  #endif


25 


26  #include <wolfssl/wolfcrypt/settings.h>


27 


28  #ifndef NO_RSA


29 


30  #include <wolfssl/wolfcrypt/rsa.h>


31 


32  #ifdef HAVE_FIPS


33  int wc_InitRsaKey(RsaKey* key, void* ptr)


34  {


35  return InitRsaKey_fips(key, ptr);


36  }


37 


38 


39  int wc_FreeRsaKey(RsaKey* key)


40  {


41  return FreeRsaKey_fips(key);


42  }


43 


44 


45  int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,


46  word32 outLen, RsaKey* key, WC_RNG* rng)


47  {


48  return RsaPublicEncrypt_fips(in, inLen, out, outLen, key, rng);


49  }


50 


51 


52  int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,


53  RsaKey* key)


54  {


55  return RsaPrivateDecryptInline_fips(in, inLen, out, key);


56  }


57 


58 


59  int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,


60  word32 outLen, RsaKey* key)


61  {


62  return RsaPrivateDecrypt_fips(in, inLen, out, outLen, key);


63  }


64 


65 


66  int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,


67  word32 outLen, RsaKey* key, WC_RNG* rng)


68  {


69  return RsaSSL_Sign_fips(in, inLen, out, outLen, key, rng);


70  }


71 


72 


73  int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)


74  {


75  return RsaSSL_VerifyInline_fips(in, inLen, out, key);


76  }


77 


78 


79  int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,


80  word32 outLen, RsaKey* key)


81  {


82  return RsaSSL_Verify_fips(in, inLen, out, outLen, key);


83  }


84 


85 


86  int wc_RsaEncryptSize(RsaKey* key)


87  {


88  return RsaEncryptSize_fips(key);


89  }


90 


91 


92  int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,


93  word32* bSz)


94  {


95  /* not specified as fips so not needing _fips */


96  return RsaFlattenPublicKey(key, a, aSz, b, bSz);


97  }


98  #ifdef WOLFSSL_KEY_GEN


99  int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)


100  {


101  return MakeRsaKey(key, size, e, rng);


102  }


103  #endif


104 


105 


106  #ifdef HAVE_CAVIUM


107  int wc_RsaInitCavium(RsaKey* key, int i)


108  {


109  return RsaInitCavium(key, i);


110  }


111 


112 


113  void wc_RsaFreeCavium(RsaKey* key)


114  {


115  RsaFreeCavium(key);


116  }


117  #endif


118 


119  /* these are functions in asn and are routed to wolfssl/wolfcrypt/asn.c


120  * wc_RsaPrivateKeyDecode


121  * wc_RsaPublicKeyDecode


122  */


123 


124  #else /* else build without fips */


125  #include <wolfssl/wolfcrypt/random.h>


126  #include <wolfssl/wolfcrypt/errorcrypt.h>


127  #include <wolfssl/wolfcrypt/logging.h>


128  #ifdef NO_INLINE


129  #include <wolfssl/wolfcrypt/misc.h>


130  #else


131  #include <wolfcrypt/src/misc.c>


132  #endif


133 


134  #ifdef HAVE_CAVIUM


135  static int InitCaviumRsaKey(RsaKey* key, void* heap);


136  static int FreeCaviumRsaKey(RsaKey* key);


137  static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,


138  word32 outLen, RsaKey* key);


139  static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,


140  word32 outLen, RsaKey* key);


141  static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,


142  word32 outLen, RsaKey* key);


143  static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,


144  word32 outLen, RsaKey* key);


145  #endif


146 


147  enum {


148  RSA_PUBLIC_ENCRYPT = 0,


149  RSA_PUBLIC_DECRYPT = 1,


150  RSA_PRIVATE_ENCRYPT = 2,


151  RSA_PRIVATE_DECRYPT = 3,


152 


153  RSA_BLOCK_TYPE_1 = 1,


154  RSA_BLOCK_TYPE_2 = 2,


155 


156  RSA_MIN_SIZE = 512,


157  RSA_MAX_SIZE = 4096,


158 


159  RSA_MIN_PAD_SZ = 11 /* seperator + 0 + pad value + 8 pads */


160  };


161 


162 


163  int wc_InitRsaKey(RsaKey* key, void* heap)


164  {


165  #ifdef HAVE_CAVIUM


166  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC)


167  return InitCaviumRsaKey(key, heap);


168  #endif


169 


170  key>type = 1; /* haven't decided yet */


171  key>heap = heap;


172 


173  /* TomsFastMath doesn't use memory allocation */


174  #ifndef USE_FAST_MATH


175  key>n.dp = key>e.dp = 0; /* public alloc parts */


176 


177  key>d.dp = key>p.dp = 0; /* private alloc parts */


178  key>q.dp = key>dP.dp = 0;


179  key>u.dp = key>dQ.dp = 0;


180  #else


181  mp_init(&key>n);


182  mp_init(&key>e);


183  mp_init(&key>d);


184  mp_init(&key>p);


185  mp_init(&key>q);


186  mp_init(&key>dP);


187  mp_init(&key>dQ);


188  mp_init(&key>u);


189  #endif


190 


191  return 0;


192  }


193 


194 


195  int wc_FreeRsaKey(RsaKey* key)


196  {


197  (void)key;


198 


199  #ifdef HAVE_CAVIUM


200  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC)


201  return FreeCaviumRsaKey(key);


202  #endif


203 


204  /* TomsFastMath doesn't use memory allocation */


205  #ifndef USE_FAST_MATH


206  if (key>type == RSA_PRIVATE) {


207  mp_clear(&key>u);


208  mp_clear(&key>dQ);


209  mp_clear(&key>dP);


210  mp_clear(&key>q);


211  mp_clear(&key>p);


212  mp_clear(&key>d);


213  }


214  mp_clear(&key>e);


215  mp_clear(&key>n);


216  #endif


217 


218  return 0;


219  }


220 


221  static int wc_RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,


222  word32 pkcsBlockLen, byte padValue, WC_RNG* rng)


223  {


224  if (inputLen == 0)


225  return 0;


226 


227  pkcsBlock[0] = 0x0; /* set first byte to zero and advance */


228  pkcsBlock++; pkcsBlockLen;


229  pkcsBlock[0] = padValue; /* insert padValue */


230 


231  if (padValue == RSA_BLOCK_TYPE_1)


232  /* pad with 0xff bytes */


233  XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen  inputLen  2);


234  else {


235  /* pad with nonzero random bytes */


236  word32 padLen = pkcsBlockLen  inputLen  1, i;


237  int ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);


238 


239  if (ret != 0)


240  return ret;


241 


242  /* remove zeros */


243  for (i = 1; i < padLen; i++)


244  if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;


245  }


246 


247  pkcsBlock[pkcsBlockLeninputLen1] = 0; /* separator */


248  XMEMCPY(pkcsBlock+pkcsBlockLeninputLen, input, inputLen);


249 


250  return 0;


251  }


252 


253 


254  /* UnPad plaintext, set start to *output, return length of plaintext,


255  * < 0 on error */


256  static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,


257  byte **output, byte padValue)


258  {


259  word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen  10) : 0,


260  invalid = 0,


261  i = 1,


262  outputLen;


263 


264  if (pkcsBlock[0] != 0x0) /* skip past zero */


265  invalid = 1;


266  pkcsBlock++; pkcsBlockLen;


267 


268  /* Require block type padValue */


269  invalid = (pkcsBlock[0] != padValue)  invalid;


270 


271  /* verify the padding until we find the separator */


272  if (padValue == RSA_BLOCK_TYPE_1) {


273  while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}


274  }


275  else {


276  while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}


277  }


278 


279  if(!(i==pkcsBlockLen  pkcsBlock[i1]==0)) {


280  WOLFSSL_MSG("RsaUnPad error, bad formatting");


281  return RSA_PAD_E;


282  }


283 


284  outputLen = pkcsBlockLen  i;


285  invalid = (outputLen > maxOutputLen)  invalid;


286 


287  if (invalid) {


288  WOLFSSL_MSG("RsaUnPad error, bad formatting");


289  return RSA_PAD_E;


290  }


291 


292  *output = (byte *)(pkcsBlock + i);


293  return outputLen;


294  }


295 


296 


297  static int wc_RsaFunction(const byte* in, word32 inLen, byte* out,


298  word32* outLen, int type, RsaKey* key)


299  {


300  #define ERROR_OUT(x) { ret = (x); goto done;}


301 


302  mp_int tmp;


303  int ret = 0;


304  word32 keyLen, len;


305 


306  if (mp_init(&tmp) != MP_OKAY)


307  return MP_INIT_E;


308 


309  if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)


310  ERROR_OUT(MP_READ_E);


311 


312  if (type == RSA_PRIVATE_DECRYPT  type == RSA_PRIVATE_ENCRYPT) {


313  #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */


314  if (mp_exptmod(&tmp, &key>d, &key>n, &tmp) != MP_OKAY)


315  ERROR_OUT(MP_EXPTMOD_E);


316  #else


317  #define INNER_ERROR_OUT(x) { ret = (x); goto inner_done; }


318 


319  mp_int tmpa, tmpb;


320 


321  if (mp_init(&tmpa) != MP_OKAY)


322  ERROR_OUT(MP_INIT_E);


323 


324  if (mp_init(&tmpb) != MP_OKAY) {


325  mp_clear(&tmpa);


326  ERROR_OUT(MP_INIT_E);


327  }


328 


329  /* tmpa = tmp^dP mod p */


330  if (mp_exptmod(&tmp, &key>dP, &key>p, &tmpa) != MP_OKAY)


331  INNER_ERROR_OUT(MP_EXPTMOD_E);


332 


333  /* tmpb = tmp^dQ mod q */


334  if (mp_exptmod(&tmp, &key>dQ, &key>q, &tmpb) != MP_OKAY)


335  INNER_ERROR_OUT(MP_EXPTMOD_E);


336 


337  /* tmp = (tmpa  tmpb) * qInv (mod p) */


338  if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY)


339  INNER_ERROR_OUT(MP_SUB_E);


340 


341  if (mp_mulmod(&tmp, &key>u, &key>p, &tmp) != MP_OKAY)


342  INNER_ERROR_OUT(MP_MULMOD_E);


343 


344  /* tmp = tmpb + q * tmp */


345  if (mp_mul(&tmp, &key>q, &tmp) != MP_OKAY)


346  INNER_ERROR_OUT(MP_MUL_E);


347 


348  if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY)


349  INNER_ERROR_OUT(MP_ADD_E);


350 


351  inner_done:


352  mp_clear(&tmpa);


353  mp_clear(&tmpb);


354 


355  if (ret != 0) return ret;


356 


357  #endif /* RSA_LOW_MEM */


358  }


359  else if (type == RSA_PUBLIC_ENCRYPT  type == RSA_PUBLIC_DECRYPT) {


360  if (mp_exptmod(&tmp, &key>e, &key>n, &tmp) != MP_OKAY)


361  ERROR_OUT(MP_EXPTMOD_E);


362  }


363  else


364  ERROR_OUT(RSA_WRONG_TYPE_E);


365 


366  keyLen = mp_unsigned_bin_size(&key>n);


367  if (keyLen > *outLen)


368  ERROR_OUT(RSA_BUFFER_E);


369 


370  len = mp_unsigned_bin_size(&tmp);


371 


372  /* pad front w/ zeros to match key length */


373  while (len < keyLen) {


374  *out++ = 0x00;


375  len++;


376  }


377 


378  *outLen = keyLen;


379 


380  /* convert */


381  if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)


382  ERROR_OUT(MP_TO_E);


383 


384  done:


385  mp_clear(&tmp);


386  if (ret == MP_EXPTMOD_E) {


387  WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem");


388  }


389  return ret;


390  }


391 


392 


393  int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,


394  RsaKey* key, WC_RNG* rng)


395  {


396  int sz, ret;


397 


398  #ifdef HAVE_CAVIUM


399  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC)


400  return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key);


401  #endif


402 


403  sz = mp_unsigned_bin_size(&key>n);


404  if (sz > (int)outLen)


405  return RSA_BUFFER_E;


406 


407  if (inLen > (word32)(sz  RSA_MIN_PAD_SZ))


408  return RSA_BUFFER_E;


409 


410  ret = wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng);


411  if (ret != 0)


412  return ret;


413 


414  if ((ret = wc_RsaFunction(out, sz, out, &outLen,


415  RSA_PUBLIC_ENCRYPT, key)) < 0)


416  sz = ret;


417 


418  return sz;


419  }


420 


421 


422  int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)


423  {


424  int ret;


425 


426  #ifdef HAVE_CAVIUM


427  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC) {


428  ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key);


429  if (ret > 0)


430  *out = in;


431  return ret;


432  }


433  #endif


434 


435  if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))


436  < 0) {


437  return ret;


438  }


439 


440  return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_2);


441  }


442 


443 


444  int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,


445  RsaKey* key)


446  {


447  int plainLen;


448  byte* tmp;


449  byte* pad = 0;


450 


451  #ifdef HAVE_CAVIUM


452  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC)


453  return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key);


454  #endif


455 


456  tmp = (byte*)XMALLOC(inLen, key>heap, DYNAMIC_TYPE_RSA);


457  if (tmp == NULL) {


458  return MEMORY_E;


459  }


460 


461  XMEMCPY(tmp, in, inLen);


462 


463  if ( (plainLen = wc_RsaPrivateDecryptInline(tmp, inLen, &pad, key) ) < 0) {


464  XFREE(tmp, key>heap, DYNAMIC_TYPE_RSA);


465  return plainLen;


466  }


467  if (plainLen > (int)outLen)


468  plainLen = BAD_FUNC_ARG;


469  else


470  XMEMCPY(out, pad, plainLen);


471 


472  ForceZero(tmp, inLen);


473  XFREE(tmp, key>heap, DYNAMIC_TYPE_RSA);


474 


475  return plainLen;


476  }


477 


478 


479  /* for Rsa Verify */


480  int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)


481  {


482  int ret;


483 


484  #ifdef HAVE_CAVIUM


485  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC) {


486  ret = CaviumRsaSSL_Verify(in, inLen, in, inLen, key);


487  if (ret > 0)


488  *out = in;


489  return ret;


490  }


491  #endif


492 


493  if ((ret = wc_RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key))


494  < 0) {


495  return ret;


496  }


497 


498  return RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1);


499  }


500 


501 


502  int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,


503  RsaKey* key)


504  {


505  int plainLen;


506  byte* tmp;


507  byte* pad = 0;


508 


509  #ifdef HAVE_CAVIUM


510  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC)


511  return CaviumRsaSSL_Verify(in, inLen, out, outLen, key);


512  #endif


513 


514  tmp = (byte*)XMALLOC(inLen, key>heap, DYNAMIC_TYPE_RSA);


515  if (tmp == NULL) {


516  return MEMORY_E;


517  }


518 


519  XMEMCPY(tmp, in, inLen);


520 


521  if ( (plainLen = wc_RsaSSL_VerifyInline(tmp, inLen, &pad, key) ) < 0) {


522  XFREE(tmp, key>heap, DYNAMIC_TYPE_RSA);


523  return plainLen;


524  }


525 


526  if (plainLen > (int)outLen)


527  plainLen = BAD_FUNC_ARG;


528  else


529  XMEMCPY(out, pad, plainLen);


530 


531  ForceZero(tmp, inLen);


532  XFREE(tmp, key>heap, DYNAMIC_TYPE_RSA);


533 


534  return plainLen;


535  }


536 


537 


538  /* for Rsa Sign */


539  int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,


540  RsaKey* key, WC_RNG* rng)


541  {


542  int sz, ret;


543 


544  #ifdef HAVE_CAVIUM


545  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC)


546  return CaviumRsaSSL_Sign(in, inLen, out, outLen, key);


547  #endif


548 


549  sz = mp_unsigned_bin_size(&key>n);


550  if (sz > (int)outLen)


551  return RSA_BUFFER_E;


552 


553  if (inLen > (word32)(sz  RSA_MIN_PAD_SZ))


554  return RSA_BUFFER_E;


555 


556  ret = wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng);


557  if (ret != 0)


558  return ret;


559 


560  if ((ret = wc_RsaFunction(out, sz, out, &outLen,


561  RSA_PRIVATE_ENCRYPT,key)) < 0)


562  sz = ret;


563 


564  return sz;


565  }


566 


567 


568  int wc_RsaEncryptSize(RsaKey* key)


569  {


570  #ifdef HAVE_CAVIUM


571  if (key>magic == WOLFSSL_RSA_CAVIUM_MAGIC)


572  return key>c_nSz;


573  #endif


574  return mp_unsigned_bin_size(&key>n);


575  }


576 


577  /* flatten RsaKey structure into individual elements (e, n) */


578  int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,


579  word32* nSz)


580  {


581  int sz, ret;


582 


583  if (key == NULL  e == NULL  eSz == NULL  n == NULL  nSz == NULL)


584  return BAD_FUNC_ARG;


585 


586  sz = mp_unsigned_bin_size(&key>e);


587  if ((word32)sz > *nSz)


588  return RSA_BUFFER_E;


589  ret = mp_to_unsigned_bin(&key>e, e);


590  if (ret != MP_OKAY)


591  return ret;


592  *eSz = (word32)sz;


593 


594  sz = mp_unsigned_bin_size(&key>n);


595  if ((word32)sz > *nSz)


596  return RSA_BUFFER_E;


597  ret = mp_to_unsigned_bin(&key>n, n);


598  if (ret != MP_OKAY)


599  return ret;


600  *nSz = (word32)sz;


601 


602  return 0;


603  }


604 


605  #ifdef WOLFSSL_KEY_GEN


606  /* Make an RSA key for size bits, with e specified, 65537 is a good e */


607  int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)


608  {


609  mp_int p, q, tmp1, tmp2, tmp3;


610  int err;


611 


612  if (key == NULL  rng == NULL)


613  return BAD_FUNC_ARG;


614 


615  if (size < RSA_MIN_SIZE  size > RSA_MAX_SIZE)


616  return BAD_FUNC_ARG;


617 


618  if (e < 3  (e & 1) == 0)


619  return BAD_FUNC_ARG;


620 


621  if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)


622  return err;


623 


624  err = mp_set_int(&tmp3, e);


625 


626  /* make p */


627  if (err == MP_OKAY) {


628  do {


629  err = mp_rand_prime(&p, size/16, rng, key>heap); /* size in bytes/2 */


630 


631  if (err == MP_OKAY)


632  err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p1 */


633 


634  if (err == MP_OKAY)


635  err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(p1, e) */


636  } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes p1 */


637  }


638 


639  /* make q */


640  if (err == MP_OKAY) {


641  do {


642  err = mp_rand_prime(&q, size/16, rng, key>heap); /* size in bytes/2 */


643 


644  if (err == MP_OKAY)


645  err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q1 */


646 


647  if (err == MP_OKAY)


648  err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(q1, e) */


649  } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes q1 */


650  }


651 


652  if (err == MP_OKAY)


653  err = mp_init_multi(&key>n, &key>e, &key>d, &key>p, &key>q, NULL);


654 


655  if (err == MP_OKAY)


656  err = mp_init_multi(&key>dP, &key>dQ, &key>u, NULL, NULL, NULL);


657 


658  if (err == MP_OKAY)


659  err = mp_sub_d(&p, 1, &tmp2); /* tmp2 = p1 */


660 


661  if (err == MP_OKAY)


662  err = mp_lcm(&tmp1, &tmp2, &tmp1); /* tmp1 = lcm(p1, q1),last loop */


663 


664  /* make key */


665  if (err == MP_OKAY)


666  err = mp_set_int(&key>e, e); /* key>e = e */


667 


668  if (err == MP_OKAY) /* key>d = 1/e mod lcm(p1, q1) */


669  err = mp_invmod(&key>e, &tmp1, &key>d);


670 


671  if (err == MP_OKAY)


672  err = mp_mul(&p, &q, &key>n); /* key>n = pq */


673 


674  if (err == MP_OKAY)


675  err = mp_sub_d(&p, 1, &tmp1);


676 


677  if (err == MP_OKAY)


678  err = mp_sub_d(&q, 1, &tmp2);


679 


680  if (err == MP_OKAY)


681  err = mp_mod(&key>d, &tmp1, &key>dP);


682 


683  if (err == MP_OKAY)


684  err = mp_mod(&key>d, &tmp2, &key>dQ);


685 


686  if (err == MP_OKAY)


687  err = mp_invmod(&q, &p, &key>u);


688 


689  if (err == MP_OKAY)


690  err = mp_copy(&p, &key>p);


691 


692  if (err == MP_OKAY)


693  err = mp_copy(&q, &key>q);


694 


695  if (err == MP_OKAY)


696  key>type = RSA_PRIVATE;


697 


698  mp_clear(&tmp3);


699  mp_clear(&tmp2);


700  mp_clear(&tmp1);


701  mp_clear(&q);


702  mp_clear(&p);


703 


704  if (err != MP_OKAY) {


705  wc_FreeRsaKey(key);


706  return err;


707  }


708 


709  return 0;


710  }


711 


712 


713  #endif /* WOLFSSL_KEY_GEN */


714 


715 


716  #ifdef HAVE_CAVIUM


717 


718  #include <cyassl/ctaocrypt/logging.h>


719  #include "cavium_common.h"


720 


721  /* Initiliaze RSA for use with Nitrox device */


722  int RsaInitCavium(RsaKey* rsa, int devId)


723  {


724  if (rsa == NULL)


725  return 1;


726 


727  if (CspAllocContext(CONTEXT_SSL, &rsa>contextHandle, devId) != 0)


728  return 1;


729 


730  rsa>devId = devId;


731  rsa>magic = WOLFSSL_RSA_CAVIUM_MAGIC;


732 


733  return 0;


734  }


735 


736 


737  /* Free RSA from use with Nitrox device */


738  void wc_RsaFreeCavium(RsaKey* rsa)


739  {


740  if (rsa == NULL)


741  return;


742 


743  CspFreeContext(CONTEXT_SSL, rsa>contextHandle, rsa>devId);


744  rsa>magic = 0;


745  }


746 


747 


748  /* Initialize cavium RSA key */


749  static int InitCaviumRsaKey(RsaKey* key, void* heap)


750  {


751  if (key == NULL)


752  return BAD_FUNC_ARG;


753 


754  key>heap = heap;


755  key>type = 1; /* don't know yet */


756 


757  key>c_n = NULL;


758  key>c_e = NULL;


759  key>c_d = NULL;


760  key>c_p = NULL;


761  key>c_q = NULL;


762  key>c_dP = NULL;


763  key>c_dQ = NULL;


764  key>c_u = NULL;


765 


766  key>c_nSz = 0;


767  key>c_eSz = 0;


768  key>c_dSz = 0;


769  key>c_pSz = 0;


770  key>c_qSz = 0;


771  key>c_dP_Sz = 0;


772  key>c_dQ_Sz = 0;


773  key>c_uSz = 0;


774 


775  return 0;


776  }


777 


778 


779  /* Free cavium RSA key */


780  static int FreeCaviumRsaKey(RsaKey* key)


781  {


782  if (key == NULL)


783  return BAD_FUNC_ARG;


784 


785  XFREE(key>c_n, key>heap, DYNAMIC_TYPE_CAVIUM_TMP);


786  XFREE(key>c_e, key>heap, DYNAMIC_TYPE_CAVIUM_TMP);


787  XFREE(key>c_d, key>heap, DYNAMIC_TYPE_CAVIUM_TMP);


788  XFREE(key>c_p, key>heap, DYNAMIC_TYPE_CAVIUM_TMP);


789  XFREE(key>c_q, key>heap, DYNAMIC_TYPE_CAVIUM_TMP);


790  XFREE(key>c_dP, key>heap, DYNAMIC_TYPE_CAVIUM_TMP);


791  XFREE(key>c_dQ, key>heap, DYNAMIC_TYPE_CAVIUM_TMP);


792  XFREE(key>c_u, key>heap, DYNAMIC_TYPE_CAVIUM_TMP);


793 


794  return InitCaviumRsaKey(key, key>heap); /* reset pointers */


795  }


796 


797 


798  static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,


799  word32 outLen, RsaKey* key)


800  {


801  word32 requestId;


802  word32 ret;


803 


804  if (key == NULL  in == NULL  out == NULL  outLen < (word32)key>c_nSz)


805  return 1;


806 


807  ret = CspPkcs1v15Enc(CAVIUM_BLOCKING, BT2, key>c_nSz, key>c_eSz,


808  (word16)inLen, key>c_n, key>c_e, (byte*)in, out,


809  &requestId, key>devId);


810  if (ret != 0) {


811  WOLFSSL_MSG("Cavium Enc BT2 failed");


812  return 1;


813  }


814  return key>c_nSz;


815  }


816 


817 


818  static INLINE void ato16(const byte* c, word16* u16)


819  {


820  *u16 = (c[0] << 8)  (c[1]);


821  }


822 


823 


824  static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,


825  word32 outLen, RsaKey* key)


826  {


827  word32 requestId;


828  word32 ret;


829  word16 outSz = (word16)outLen;


830 


831  if (key == NULL  in == NULL  out == NULL  inLen != (word32)key>c_nSz)


832  return 1;


833 


834  ret = CspPkcs1v15CrtDec(CAVIUM_BLOCKING, BT2, key>c_nSz, key>c_q,


835  key>c_dQ, key>c_p, key>c_dP, key>c_u,


836  (byte*)in, &outSz, out, &requestId, key>devId);


837  if (ret != 0) {


838  WOLFSSL_MSG("Cavium CRT Dec BT2 failed");


839  return 1;


840  }


841  ato16((const byte*)&outSz, &outSz);


842 


843  return outSz;


844  }


845 


846 


847  static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,


848  word32 outLen, RsaKey* key)


849  {


850  word32 requestId;


851  word32 ret;


852 


853  if (key == NULL  in == NULL  out == NULL  inLen == 0  outLen <


854  (word32)key>c_nSz)


855  return 1;


856 


857  ret = CspPkcs1v15CrtEnc(CAVIUM_BLOCKING, BT1, key>c_nSz, (word16)inLen,


858  key>c_q, key>c_dQ, key>c_p, key>c_dP, key>c_u,


859  (byte*)in, out, &requestId, key>devId);


860  if (ret != 0) {


861  WOLFSSL_MSG("Cavium CRT Enc BT1 failed");


862  return 1;


863  }


864  return key>c_nSz;


865  }


866 


867 


868  static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,


869  word32 outLen, RsaKey* key)


870  {


871  word32 requestId;


872  word32 ret;


873  word16 outSz = (word16)outLen;


874 


875  if (key == NULL  in == NULL  out == NULL  inLen != (word32)key>c_nSz)


876  return 1;


877 


878  ret = CspPkcs1v15Dec(CAVIUM_BLOCKING, BT1, key>c_nSz, key>c_eSz,


879  key>c_n, key>c_e, (byte*)in, &outSz, out,


880  &requestId, key>devId);


881  if (ret != 0) {


882  WOLFSSL_MSG("Cavium Dec BT1 failed");


883  return 1;


884  }


885  outSz = ntohs(outSz);


886 


887  return outSz;


888  }


889 


890 


891  #endif /* HAVE_CAVIUM */


892 


893  #endif /* HAVE_FIPS */


894  #endif /* NO_RSA */


895 

