cyassl re-port with cellular comms, PSK test

Dependencies:   VodafoneUSBModem_bleedingedge2 mbed-rtos mbed-src

Committer:
ashleymills
Date:
Fri Apr 26 16:59:36 2013 +0000
Revision:
1:b211d97b0068
Parent:
0:e979170e02e7
nothing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:e979170e02e7 1 /* rsa.c
ashleymills 0:e979170e02e7 2 *
ashleymills 0:e979170e02e7 3 * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
ashleymills 0:e979170e02e7 4 *
ashleymills 0:e979170e02e7 5 * This file is part of CyaSSL.
ashleymills 0:e979170e02e7 6 *
ashleymills 0:e979170e02e7 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:e979170e02e7 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:e979170e02e7 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:e979170e02e7 10 * (at your option) any later version.
ashleymills 0:e979170e02e7 11 *
ashleymills 0:e979170e02e7 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:e979170e02e7 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:e979170e02e7 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:e979170e02e7 15 * GNU General Public License for more details.
ashleymills 0:e979170e02e7 16 *
ashleymills 0:e979170e02e7 17 * You should have received a copy of the GNU General Public License
ashleymills 0:e979170e02e7 18 * along with this program; if not, write to the Free Software
ashleymills 0:e979170e02e7 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:e979170e02e7 20 */
ashleymills 0:e979170e02e7 21
ashleymills 0:e979170e02e7 22
ashleymills 0:e979170e02e7 23 #ifdef HAVE_CONFIG_H
ashleymills 0:e979170e02e7 24 #include <config.h>
ashleymills 0:e979170e02e7 25 #endif
ashleymills 0:e979170e02e7 26
ashleymills 0:e979170e02e7 27 #ifndef NO_RSA
ashleymills 0:e979170e02e7 28
ashleymills 0:e979170e02e7 29 #include <cyassl/ctaocrypt/rsa.h>
ashleymills 0:e979170e02e7 30 #include <cyassl/ctaocrypt/random.h>
ashleymills 0:e979170e02e7 31 #include <cyassl/ctaocrypt/error.h>
ashleymills 0:e979170e02e7 32 #include <cyassl/ctaocrypt/logging.h>
ashleymills 0:e979170e02e7 33
ashleymills 0:e979170e02e7 34 #ifdef SHOW_GEN
ashleymills 0:e979170e02e7 35 #ifdef FREESCALE_MQX
ashleymills 0:e979170e02e7 36 #include <fio.h>
ashleymills 0:e979170e02e7 37 #else
ashleymills 0:e979170e02e7 38 #include <stdio.h>
ashleymills 0:e979170e02e7 39 #endif
ashleymills 0:e979170e02e7 40 #endif
ashleymills 0:e979170e02e7 41
ashleymills 0:e979170e02e7 42 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 43 static void InitCaviumRsaKey(RsaKey* key, void* heap);
ashleymills 0:e979170e02e7 44 static void FreeCaviumRsaKey(RsaKey* key);
ashleymills 0:e979170e02e7 45 static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
ashleymills 0:e979170e02e7 46 word32 outLen, RsaKey* key);
ashleymills 0:e979170e02e7 47 static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
ashleymills 0:e979170e02e7 48 word32 outLen, RsaKey* key);
ashleymills 0:e979170e02e7 49 static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,
ashleymills 0:e979170e02e7 50 word32 outLen, RsaKey* key);
ashleymills 0:e979170e02e7 51 static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,
ashleymills 0:e979170e02e7 52 word32 outLen, RsaKey* key);
ashleymills 0:e979170e02e7 53 #endif
ashleymills 0:e979170e02e7 54
ashleymills 0:e979170e02e7 55 enum {
ashleymills 0:e979170e02e7 56 RSA_PUBLIC_ENCRYPT = 0,
ashleymills 0:e979170e02e7 57 RSA_PUBLIC_DECRYPT = 1,
ashleymills 0:e979170e02e7 58 RSA_PRIVATE_ENCRYPT = 2,
ashleymills 0:e979170e02e7 59 RSA_PRIVATE_DECRYPT = 3,
ashleymills 0:e979170e02e7 60
ashleymills 0:e979170e02e7 61 RSA_BLOCK_TYPE_1 = 1,
ashleymills 0:e979170e02e7 62 RSA_BLOCK_TYPE_2 = 2,
ashleymills 0:e979170e02e7 63
ashleymills 0:e979170e02e7 64 RSA_MIN_SIZE = 512,
ashleymills 0:e979170e02e7 65 RSA_MAX_SIZE = 4096,
ashleymills 0:e979170e02e7 66
ashleymills 0:e979170e02e7 67 RSA_MIN_PAD_SZ = 11 /* seperator + 0 + pad value + 8 pads */
ashleymills 0:e979170e02e7 68 };
ashleymills 0:e979170e02e7 69
ashleymills 0:e979170e02e7 70
ashleymills 0:e979170e02e7 71 void InitRsaKey(RsaKey* key, void* heap)
ashleymills 0:e979170e02e7 72 {
ashleymills 0:e979170e02e7 73 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 74 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
ashleymills 0:e979170e02e7 75 return InitCaviumRsaKey(key, heap);
ashleymills 0:e979170e02e7 76 #endif
ashleymills 0:e979170e02e7 77
ashleymills 0:e979170e02e7 78 key->type = -1; /* haven't decided yet */
ashleymills 0:e979170e02e7 79 key->heap = heap;
ashleymills 0:e979170e02e7 80
ashleymills 0:e979170e02e7 81 /* TomsFastMath doesn't use memory allocation */
ashleymills 0:e979170e02e7 82 #ifndef USE_FAST_MATH
ashleymills 0:e979170e02e7 83 key->n.dp = key->e.dp = 0; /* public alloc parts */
ashleymills 0:e979170e02e7 84
ashleymills 0:e979170e02e7 85 key->d.dp = key->p.dp = 0; /* private alloc parts */
ashleymills 0:e979170e02e7 86 key->q.dp = key->dP.dp = 0;
ashleymills 0:e979170e02e7 87 key->u.dp = key->dQ.dp = 0;
ashleymills 0:e979170e02e7 88 #endif
ashleymills 0:e979170e02e7 89 }
ashleymills 0:e979170e02e7 90
ashleymills 0:e979170e02e7 91
ashleymills 0:e979170e02e7 92 void FreeRsaKey(RsaKey* key)
ashleymills 0:e979170e02e7 93 {
ashleymills 0:e979170e02e7 94 (void)key;
ashleymills 0:e979170e02e7 95
ashleymills 0:e979170e02e7 96 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 97 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
ashleymills 0:e979170e02e7 98 return FreeCaviumRsaKey(key);
ashleymills 0:e979170e02e7 99 #endif
ashleymills 0:e979170e02e7 100
ashleymills 0:e979170e02e7 101 /* TomsFastMath doesn't use memory allocation */
ashleymills 0:e979170e02e7 102 #ifndef USE_FAST_MATH
ashleymills 0:e979170e02e7 103 if (key->type == RSA_PRIVATE) {
ashleymills 0:e979170e02e7 104 mp_clear(&key->u);
ashleymills 0:e979170e02e7 105 mp_clear(&key->dQ);
ashleymills 0:e979170e02e7 106 mp_clear(&key->dP);
ashleymills 0:e979170e02e7 107 mp_clear(&key->q);
ashleymills 0:e979170e02e7 108 mp_clear(&key->p);
ashleymills 0:e979170e02e7 109 mp_clear(&key->d);
ashleymills 0:e979170e02e7 110 }
ashleymills 0:e979170e02e7 111 mp_clear(&key->e);
ashleymills 0:e979170e02e7 112 mp_clear(&key->n);
ashleymills 0:e979170e02e7 113 #endif
ashleymills 0:e979170e02e7 114 }
ashleymills 0:e979170e02e7 115
ashleymills 0:e979170e02e7 116 static void RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
ashleymills 0:e979170e02e7 117 word32 pkcsBlockLen, byte padValue, RNG* rng)
ashleymills 0:e979170e02e7 118 {
ashleymills 0:e979170e02e7 119 if (inputLen == 0) return;
ashleymills 0:e979170e02e7 120
ashleymills 0:e979170e02e7 121 pkcsBlock[0] = 0x0; /* set first byte to zero and advance */
ashleymills 0:e979170e02e7 122 pkcsBlock++; pkcsBlockLen--;
ashleymills 0:e979170e02e7 123 pkcsBlock[0] = padValue; /* insert padValue */
ashleymills 0:e979170e02e7 124
ashleymills 0:e979170e02e7 125 if (padValue == RSA_BLOCK_TYPE_1)
ashleymills 0:e979170e02e7 126 /* pad with 0xff bytes */
ashleymills 0:e979170e02e7 127 XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
ashleymills 0:e979170e02e7 128 else {
ashleymills 0:e979170e02e7 129 /* pad with non-zero random bytes */
ashleymills 0:e979170e02e7 130 word32 padLen = pkcsBlockLen - inputLen - 1, i;
ashleymills 0:e979170e02e7 131 RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);
ashleymills 0:e979170e02e7 132
ashleymills 0:e979170e02e7 133 /* remove zeros */
ashleymills 0:e979170e02e7 134 for (i = 1; i < padLen; i++)
ashleymills 0:e979170e02e7 135 if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
ashleymills 0:e979170e02e7 136 }
ashleymills 0:e979170e02e7 137
ashleymills 0:e979170e02e7 138 pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */
ashleymills 0:e979170e02e7 139 XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
ashleymills 0:e979170e02e7 140 }
ashleymills 0:e979170e02e7 141
ashleymills 0:e979170e02e7 142
ashleymills 0:e979170e02e7 143 static word32 RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
ashleymills 0:e979170e02e7 144 byte **output, byte padValue)
ashleymills 0:e979170e02e7 145 {
ashleymills 0:e979170e02e7 146 word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0,
ashleymills 0:e979170e02e7 147 invalid = 0,
ashleymills 0:e979170e02e7 148 i = 1,
ashleymills 0:e979170e02e7 149 outputLen;
ashleymills 0:e979170e02e7 150
ashleymills 0:e979170e02e7 151 if (pkcsBlock[0] != 0x0) /* skip past zero */
ashleymills 0:e979170e02e7 152 invalid = 1;
ashleymills 0:e979170e02e7 153 pkcsBlock++; pkcsBlockLen--;
ashleymills 0:e979170e02e7 154
ashleymills 0:e979170e02e7 155 /* Require block type padValue */
ashleymills 0:e979170e02e7 156 invalid = (pkcsBlock[0] != padValue) || invalid;
ashleymills 0:e979170e02e7 157
ashleymills 0:e979170e02e7 158 /* skip past the padding until we find the separator */
ashleymills 0:e979170e02e7 159 while (i<pkcsBlockLen && pkcsBlock[i++]) { /* null body */
ashleymills 0:e979170e02e7 160 }
ashleymills 0:e979170e02e7 161 if(!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
ashleymills 0:e979170e02e7 162 CYASSL_MSG("RsaUnPad error, bad formatting");
ashleymills 0:e979170e02e7 163 return 0;
ashleymills 0:e979170e02e7 164 }
ashleymills 0:e979170e02e7 165
ashleymills 0:e979170e02e7 166 outputLen = pkcsBlockLen - i;
ashleymills 0:e979170e02e7 167 invalid = (outputLen > maxOutputLen) || invalid;
ashleymills 0:e979170e02e7 168
ashleymills 0:e979170e02e7 169 if (invalid) {
ashleymills 0:e979170e02e7 170 CYASSL_MSG("RsaUnPad error, bad formatting");
ashleymills 0:e979170e02e7 171 return 0;
ashleymills 0:e979170e02e7 172 }
ashleymills 0:e979170e02e7 173
ashleymills 0:e979170e02e7 174 *output = (byte *)(pkcsBlock + i);
ashleymills 0:e979170e02e7 175 return outputLen;
ashleymills 0:e979170e02e7 176 }
ashleymills 0:e979170e02e7 177
ashleymills 0:e979170e02e7 178
ashleymills 0:e979170e02e7 179 static int RsaFunction(const byte* in, word32 inLen, byte* out, word32* outLen,
ashleymills 0:e979170e02e7 180 int type, RsaKey* key)
ashleymills 0:e979170e02e7 181 {
ashleymills 0:e979170e02e7 182 #define ERROR_OUT(x) { ret = x; goto done;}
ashleymills 0:e979170e02e7 183
ashleymills 0:e979170e02e7 184 mp_int tmp;
ashleymills 0:e979170e02e7 185 int ret = 0;
ashleymills 0:e979170e02e7 186 word32 keyLen, len;
ashleymills 0:e979170e02e7 187
ashleymills 0:e979170e02e7 188 if (mp_init(&tmp) != MP_OKAY)
ashleymills 0:e979170e02e7 189 return MP_INIT_E;
ashleymills 0:e979170e02e7 190
ashleymills 0:e979170e02e7 191 if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
ashleymills 0:e979170e02e7 192 ERROR_OUT(MP_READ_E);
ashleymills 0:e979170e02e7 193
ashleymills 0:e979170e02e7 194 if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
ashleymills 0:e979170e02e7 195 #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */
ashleymills 0:e979170e02e7 196 if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY)
ashleymills 0:e979170e02e7 197 ERROR_OUT(MP_EXPTMOD_E);
ashleymills 0:e979170e02e7 198 #else
ashleymills 0:e979170e02e7 199 #define INNER_ERROR_OUT(x) { ret = x; goto inner_done; }
ashleymills 0:e979170e02e7 200
ashleymills 0:e979170e02e7 201 mp_int tmpa, tmpb;
ashleymills 0:e979170e02e7 202
ashleymills 0:e979170e02e7 203 if (mp_init(&tmpa) != MP_OKAY)
ashleymills 0:e979170e02e7 204 ERROR_OUT(MP_INIT_E);
ashleymills 0:e979170e02e7 205
ashleymills 0:e979170e02e7 206 if (mp_init(&tmpb) != MP_OKAY) {
ashleymills 0:e979170e02e7 207 mp_clear(&tmpa);
ashleymills 0:e979170e02e7 208 ERROR_OUT(MP_INIT_E);
ashleymills 0:e979170e02e7 209 }
ashleymills 0:e979170e02e7 210
ashleymills 0:e979170e02e7 211 /* tmpa = tmp^dP mod p */
ashleymills 0:e979170e02e7 212 if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY)
ashleymills 0:e979170e02e7 213 INNER_ERROR_OUT(MP_EXPTMOD_E);
ashleymills 0:e979170e02e7 214
ashleymills 0:e979170e02e7 215 /* tmpb = tmp^dQ mod q */
ashleymills 0:e979170e02e7 216 if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY)
ashleymills 0:e979170e02e7 217 INNER_ERROR_OUT(MP_EXPTMOD_E);
ashleymills 0:e979170e02e7 218
ashleymills 0:e979170e02e7 219 /* tmp = (tmpa - tmpb) * qInv (mod p) */
ashleymills 0:e979170e02e7 220 if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY)
ashleymills 0:e979170e02e7 221 INNER_ERROR_OUT(MP_SUB_E);
ashleymills 0:e979170e02e7 222
ashleymills 0:e979170e02e7 223 if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY)
ashleymills 0:e979170e02e7 224 INNER_ERROR_OUT(MP_MULMOD_E);
ashleymills 0:e979170e02e7 225
ashleymills 0:e979170e02e7 226 /* tmp = tmpb + q * tmp */
ashleymills 0:e979170e02e7 227 if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY)
ashleymills 0:e979170e02e7 228 INNER_ERROR_OUT(MP_MUL_E);
ashleymills 0:e979170e02e7 229
ashleymills 0:e979170e02e7 230 if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY)
ashleymills 0:e979170e02e7 231 INNER_ERROR_OUT(MP_ADD_E);
ashleymills 0:e979170e02e7 232
ashleymills 0:e979170e02e7 233 inner_done:
ashleymills 0:e979170e02e7 234 mp_clear(&tmpa);
ashleymills 0:e979170e02e7 235 mp_clear(&tmpb);
ashleymills 0:e979170e02e7 236
ashleymills 0:e979170e02e7 237 if (ret != 0) return ret;
ashleymills 0:e979170e02e7 238
ashleymills 0:e979170e02e7 239 #endif /* RSA_LOW_MEM */
ashleymills 0:e979170e02e7 240 }
ashleymills 0:e979170e02e7 241 else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) {
ashleymills 0:e979170e02e7 242 if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
ashleymills 0:e979170e02e7 243 ERROR_OUT(MP_EXPTMOD_E);
ashleymills 0:e979170e02e7 244 }
ashleymills 0:e979170e02e7 245 else
ashleymills 0:e979170e02e7 246 ERROR_OUT(RSA_WRONG_TYPE_E);
ashleymills 0:e979170e02e7 247
ashleymills 0:e979170e02e7 248 keyLen = mp_unsigned_bin_size(&key->n);
ashleymills 0:e979170e02e7 249 if (keyLen > *outLen)
ashleymills 0:e979170e02e7 250 ERROR_OUT(RSA_BUFFER_E);
ashleymills 0:e979170e02e7 251
ashleymills 0:e979170e02e7 252 len = mp_unsigned_bin_size(&tmp);
ashleymills 0:e979170e02e7 253
ashleymills 0:e979170e02e7 254 /* pad front w/ zeros to match key length */
ashleymills 0:e979170e02e7 255 while (len < keyLen) {
ashleymills 0:e979170e02e7 256 *out++ = 0x00;
ashleymills 0:e979170e02e7 257 len++;
ashleymills 0:e979170e02e7 258 }
ashleymills 0:e979170e02e7 259
ashleymills 0:e979170e02e7 260 *outLen = keyLen;
ashleymills 0:e979170e02e7 261
ashleymills 0:e979170e02e7 262 /* convert */
ashleymills 0:e979170e02e7 263 if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
ashleymills 0:e979170e02e7 264 ERROR_OUT(MP_TO_E);
ashleymills 0:e979170e02e7 265
ashleymills 0:e979170e02e7 266 done:
ashleymills 0:e979170e02e7 267 mp_clear(&tmp);
ashleymills 0:e979170e02e7 268 return ret;
ashleymills 0:e979170e02e7 269 }
ashleymills 0:e979170e02e7 270
ashleymills 0:e979170e02e7 271
ashleymills 0:e979170e02e7 272 int RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
ashleymills 0:e979170e02e7 273 RsaKey* key, RNG* rng)
ashleymills 0:e979170e02e7 274 {
ashleymills 0:e979170e02e7 275 int sz, ret;
ashleymills 0:e979170e02e7 276
ashleymills 0:e979170e02e7 277 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 278 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
ashleymills 0:e979170e02e7 279 return CaviumRsaPublicEncrypt(in, inLen, out, outLen, key);
ashleymills 0:e979170e02e7 280 #endif
ashleymills 0:e979170e02e7 281
ashleymills 0:e979170e02e7 282 sz = mp_unsigned_bin_size(&key->n);
ashleymills 0:e979170e02e7 283 if (sz > (int)outLen)
ashleymills 0:e979170e02e7 284 return RSA_BUFFER_E;
ashleymills 0:e979170e02e7 285
ashleymills 0:e979170e02e7 286 if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
ashleymills 0:e979170e02e7 287 return RSA_BUFFER_E;
ashleymills 0:e979170e02e7 288
ashleymills 0:e979170e02e7 289 RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2, rng);
ashleymills 0:e979170e02e7 290
ashleymills 0:e979170e02e7 291 if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PUBLIC_ENCRYPT, key)) < 0)
ashleymills 0:e979170e02e7 292 sz = ret;
ashleymills 0:e979170e02e7 293
ashleymills 0:e979170e02e7 294 return sz;
ashleymills 0:e979170e02e7 295 }
ashleymills 0:e979170e02e7 296
ashleymills 0:e979170e02e7 297
ashleymills 0:e979170e02e7 298 int RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
ashleymills 0:e979170e02e7 299 {
ashleymills 0:e979170e02e7 300 int plainLen, ret;
ashleymills 0:e979170e02e7 301
ashleymills 0:e979170e02e7 302 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 303 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) {
ashleymills 0:e979170e02e7 304 ret = CaviumRsaPrivateDecrypt(in, inLen, in, inLen, key);
ashleymills 0:e979170e02e7 305 if (ret > 0)
ashleymills 0:e979170e02e7 306 *out = in;
ashleymills 0:e979170e02e7 307 return ret;
ashleymills 0:e979170e02e7 308 }
ashleymills 0:e979170e02e7 309 #endif
ashleymills 0:e979170e02e7 310
ashleymills 0:e979170e02e7 311 if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
ashleymills 0:e979170e02e7 312 < 0) {
ashleymills 0:e979170e02e7 313 return ret;
ashleymills 0:e979170e02e7 314 }
ashleymills 0:e979170e02e7 315
ashleymills 0:e979170e02e7 316 plainLen = RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_2);
ashleymills 0:e979170e02e7 317
ashleymills 0:e979170e02e7 318 return plainLen;
ashleymills 0:e979170e02e7 319 }
ashleymills 0:e979170e02e7 320
ashleymills 0:e979170e02e7 321
ashleymills 0:e979170e02e7 322 int RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
ashleymills 0:e979170e02e7 323 RsaKey* key)
ashleymills 0:e979170e02e7 324 {
ashleymills 0:e979170e02e7 325 int plainLen, ret;
ashleymills 0:e979170e02e7 326 byte* tmp;
ashleymills 0:e979170e02e7 327 byte* pad = 0;
ashleymills 0:e979170e02e7 328
ashleymills 0:e979170e02e7 329 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 330 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
ashleymills 0:e979170e02e7 331 return CaviumRsaPrivateDecrypt(in, inLen, out, outLen, key);
ashleymills 0:e979170e02e7 332 #endif
ashleymills 0:e979170e02e7 333
ashleymills 0:e979170e02e7 334 tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 335 if (tmp == NULL) {
ashleymills 0:e979170e02e7 336 return MEMORY_E;
ashleymills 0:e979170e02e7 337 }
ashleymills 0:e979170e02e7 338
ashleymills 0:e979170e02e7 339 XMEMCPY(tmp, in, inLen);
ashleymills 0:e979170e02e7 340
ashleymills 0:e979170e02e7 341 if ((ret = plainLen = RsaPrivateDecryptInline(tmp, inLen, &pad, key))
ashleymills 0:e979170e02e7 342 < 0) {
ashleymills 0:e979170e02e7 343 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 344 return ret;
ashleymills 0:e979170e02e7 345 }
ashleymills 0:e979170e02e7 346 if (plainLen > (int)outLen)
ashleymills 0:e979170e02e7 347 plainLen = BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 348 else
ashleymills 0:e979170e02e7 349 XMEMCPY(out, pad, plainLen);
ashleymills 0:e979170e02e7 350 XMEMSET(tmp, 0x00, inLen);
ashleymills 0:e979170e02e7 351
ashleymills 0:e979170e02e7 352 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 353 return plainLen;
ashleymills 0:e979170e02e7 354 }
ashleymills 0:e979170e02e7 355
ashleymills 0:e979170e02e7 356
ashleymills 0:e979170e02e7 357 /* for Rsa Verify */
ashleymills 0:e979170e02e7 358 int RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
ashleymills 0:e979170e02e7 359 {
ashleymills 0:e979170e02e7 360 int plainLen, ret;
ashleymills 0:e979170e02e7 361
ashleymills 0:e979170e02e7 362 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 363 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC) {
ashleymills 0:e979170e02e7 364 ret = CaviumRsaSSL_Verify(in, inLen, in, inLen, key);
ashleymills 0:e979170e02e7 365 if (ret > 0)
ashleymills 0:e979170e02e7 366 *out = in;
ashleymills 0:e979170e02e7 367 return ret;
ashleymills 0:e979170e02e7 368 }
ashleymills 0:e979170e02e7 369 #endif
ashleymills 0:e979170e02e7 370
ashleymills 0:e979170e02e7 371 if ((ret = RsaFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key))
ashleymills 0:e979170e02e7 372 < 0) {
ashleymills 0:e979170e02e7 373 return ret;
ashleymills 0:e979170e02e7 374 }
ashleymills 0:e979170e02e7 375
ashleymills 0:e979170e02e7 376 plainLen = RsaUnPad(in, inLen, out, RSA_BLOCK_TYPE_1);
ashleymills 0:e979170e02e7 377
ashleymills 0:e979170e02e7 378 return plainLen;
ashleymills 0:e979170e02e7 379 }
ashleymills 0:e979170e02e7 380
ashleymills 0:e979170e02e7 381
ashleymills 0:e979170e02e7 382 int RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
ashleymills 0:e979170e02e7 383 RsaKey* key)
ashleymills 0:e979170e02e7 384 {
ashleymills 0:e979170e02e7 385 int plainLen, ret;
ashleymills 0:e979170e02e7 386 byte* tmp;
ashleymills 0:e979170e02e7 387 byte* pad = 0;
ashleymills 0:e979170e02e7 388
ashleymills 0:e979170e02e7 389 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 390 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
ashleymills 0:e979170e02e7 391 return CaviumRsaSSL_Verify(in, inLen, out, outLen, key);
ashleymills 0:e979170e02e7 392 #endif
ashleymills 0:e979170e02e7 393
ashleymills 0:e979170e02e7 394 tmp = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 395 if (tmp == NULL) {
ashleymills 0:e979170e02e7 396 return MEMORY_E;
ashleymills 0:e979170e02e7 397 }
ashleymills 0:e979170e02e7 398
ashleymills 0:e979170e02e7 399 XMEMCPY(tmp, in, inLen);
ashleymills 0:e979170e02e7 400
ashleymills 0:e979170e02e7 401 if ((ret = plainLen = RsaSSL_VerifyInline(tmp, inLen, &pad, key))
ashleymills 0:e979170e02e7 402 < 0) {
ashleymills 0:e979170e02e7 403 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 404 return ret;
ashleymills 0:e979170e02e7 405 }
ashleymills 0:e979170e02e7 406
ashleymills 0:e979170e02e7 407 if (plainLen > (int)outLen)
ashleymills 0:e979170e02e7 408 plainLen = BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 409 else
ashleymills 0:e979170e02e7 410 XMEMCPY(out, pad, plainLen);
ashleymills 0:e979170e02e7 411 XMEMSET(tmp, 0x00, inLen);
ashleymills 0:e979170e02e7 412
ashleymills 0:e979170e02e7 413 XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 414 return plainLen;
ashleymills 0:e979170e02e7 415 }
ashleymills 0:e979170e02e7 416
ashleymills 0:e979170e02e7 417
ashleymills 0:e979170e02e7 418 /* for Rsa Sign */
ashleymills 0:e979170e02e7 419 int RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
ashleymills 0:e979170e02e7 420 RsaKey* key, RNG* rng)
ashleymills 0:e979170e02e7 421 {
ashleymills 0:e979170e02e7 422 int sz, ret;
ashleymills 0:e979170e02e7 423
ashleymills 0:e979170e02e7 424 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 425 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
ashleymills 0:e979170e02e7 426 return CaviumRsaSSL_Sign(in, inLen, out, outLen, key);
ashleymills 0:e979170e02e7 427 #endif
ashleymills 0:e979170e02e7 428
ashleymills 0:e979170e02e7 429 sz = mp_unsigned_bin_size(&key->n);
ashleymills 0:e979170e02e7 430 if (sz > (int)outLen)
ashleymills 0:e979170e02e7 431 return RSA_BUFFER_E;
ashleymills 0:e979170e02e7 432
ashleymills 0:e979170e02e7 433 if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
ashleymills 0:e979170e02e7 434 return RSA_BUFFER_E;
ashleymills 0:e979170e02e7 435
ashleymills 0:e979170e02e7 436 RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng);
ashleymills 0:e979170e02e7 437
ashleymills 0:e979170e02e7 438 if ((ret = RsaFunction(out, sz, out, &outLen, RSA_PRIVATE_ENCRYPT,key)) < 0)
ashleymills 0:e979170e02e7 439 sz = ret;
ashleymills 0:e979170e02e7 440
ashleymills 0:e979170e02e7 441 return sz;
ashleymills 0:e979170e02e7 442 }
ashleymills 0:e979170e02e7 443
ashleymills 0:e979170e02e7 444
ashleymills 0:e979170e02e7 445 int RsaEncryptSize(RsaKey* key)
ashleymills 0:e979170e02e7 446 {
ashleymills 0:e979170e02e7 447 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 448 if (key->magic == CYASSL_RSA_CAVIUM_MAGIC)
ashleymills 0:e979170e02e7 449 return key->c_nSz;
ashleymills 0:e979170e02e7 450 #endif
ashleymills 0:e979170e02e7 451 return mp_unsigned_bin_size(&key->n);
ashleymills 0:e979170e02e7 452 }
ashleymills 0:e979170e02e7 453
ashleymills 0:e979170e02e7 454
ashleymills 0:e979170e02e7 455 #ifdef CYASSL_KEY_GEN
ashleymills 0:e979170e02e7 456
ashleymills 0:e979170e02e7 457 static const int USE_BBS = 1;
ashleymills 0:e979170e02e7 458
ashleymills 0:e979170e02e7 459 static int rand_prime(mp_int* N, int len, RNG* rng, void* heap)
ashleymills 0:e979170e02e7 460 {
ashleymills 0:e979170e02e7 461 int err, res, type;
ashleymills 0:e979170e02e7 462 byte* buf;
ashleymills 0:e979170e02e7 463
ashleymills 0:e979170e02e7 464 (void)heap;
ashleymills 0:e979170e02e7 465 if (N == NULL || rng == NULL)
ashleymills 0:e979170e02e7 466 return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 467
ashleymills 0:e979170e02e7 468 /* get type */
ashleymills 0:e979170e02e7 469 if (len < 0) {
ashleymills 0:e979170e02e7 470 type = USE_BBS;
ashleymills 0:e979170e02e7 471 len = -len;
ashleymills 0:e979170e02e7 472 } else {
ashleymills 0:e979170e02e7 473 type = 0;
ashleymills 0:e979170e02e7 474 }
ashleymills 0:e979170e02e7 475
ashleymills 0:e979170e02e7 476 /* allow sizes between 2 and 512 bytes for a prime size */
ashleymills 0:e979170e02e7 477 if (len < 2 || len > 512) {
ashleymills 0:e979170e02e7 478 return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 479 }
ashleymills 0:e979170e02e7 480
ashleymills 0:e979170e02e7 481 /* allocate buffer to work with */
ashleymills 0:e979170e02e7 482 buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 483 if (buf == NULL) {
ashleymills 0:e979170e02e7 484 return MEMORY_E;
ashleymills 0:e979170e02e7 485 }
ashleymills 0:e979170e02e7 486 XMEMSET(buf, 0, len);
ashleymills 0:e979170e02e7 487
ashleymills 0:e979170e02e7 488 do {
ashleymills 0:e979170e02e7 489 #ifdef SHOW_GEN
ashleymills 0:e979170e02e7 490 printf(".");
ashleymills 0:e979170e02e7 491 fflush(stdout);
ashleymills 0:e979170e02e7 492 #endif
ashleymills 0:e979170e02e7 493 /* generate value */
ashleymills 0:e979170e02e7 494 RNG_GenerateBlock(rng, buf, len);
ashleymills 0:e979170e02e7 495
ashleymills 0:e979170e02e7 496 /* munge bits */
ashleymills 0:e979170e02e7 497 buf[0] |= 0x80 | 0x40;
ashleymills 0:e979170e02e7 498 buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
ashleymills 0:e979170e02e7 499
ashleymills 0:e979170e02e7 500 /* load value */
ashleymills 0:e979170e02e7 501 if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) {
ashleymills 0:e979170e02e7 502 XFREE(buf, heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 503 return err;
ashleymills 0:e979170e02e7 504 }
ashleymills 0:e979170e02e7 505
ashleymills 0:e979170e02e7 506 /* test */
ashleymills 0:e979170e02e7 507 if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) {
ashleymills 0:e979170e02e7 508 XFREE(buf, heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 509 return err;
ashleymills 0:e979170e02e7 510 }
ashleymills 0:e979170e02e7 511 } while (res == MP_NO);
ashleymills 0:e979170e02e7 512
ashleymills 0:e979170e02e7 513 #ifdef LTC_CLEAN_STACK
ashleymills 0:e979170e02e7 514 XMEMSET(buf, 0, len);
ashleymills 0:e979170e02e7 515 #endif
ashleymills 0:e979170e02e7 516
ashleymills 0:e979170e02e7 517 XFREE(buf, heap, DYNAMIC_TYPE_RSA);
ashleymills 0:e979170e02e7 518 return 0;
ashleymills 0:e979170e02e7 519 }
ashleymills 0:e979170e02e7 520
ashleymills 0:e979170e02e7 521
ashleymills 0:e979170e02e7 522 /* Make an RSA key for size bits, with e specified, 65537 is a good e */
ashleymills 0:e979170e02e7 523 int MakeRsaKey(RsaKey* key, int size, long e, RNG* rng)
ashleymills 0:e979170e02e7 524 {
ashleymills 0:e979170e02e7 525 mp_int p, q, tmp1, tmp2, tmp3;
ashleymills 0:e979170e02e7 526 int err;
ashleymills 0:e979170e02e7 527
ashleymills 0:e979170e02e7 528 if (key == NULL || rng == NULL)
ashleymills 0:e979170e02e7 529 return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 530
ashleymills 0:e979170e02e7 531 if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
ashleymills 0:e979170e02e7 532 return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 533
ashleymills 0:e979170e02e7 534 if (e < 3 || (e & 1) == 0)
ashleymills 0:e979170e02e7 535 return BAD_FUNC_ARG;
ashleymills 0:e979170e02e7 536
ashleymills 0:e979170e02e7 537 if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
ashleymills 0:e979170e02e7 538 return err;
ashleymills 0:e979170e02e7 539
ashleymills 0:e979170e02e7 540 err = mp_set_int(&tmp3, e);
ashleymills 0:e979170e02e7 541
ashleymills 0:e979170e02e7 542 /* make p */
ashleymills 0:e979170e02e7 543 if (err == MP_OKAY) {
ashleymills 0:e979170e02e7 544 do {
ashleymills 0:e979170e02e7 545 err = rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */
ashleymills 0:e979170e02e7 546
ashleymills 0:e979170e02e7 547 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 548 err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */
ashleymills 0:e979170e02e7 549
ashleymills 0:e979170e02e7 550 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 551 err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(p-1, e) */
ashleymills 0:e979170e02e7 552 } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes p-1 */
ashleymills 0:e979170e02e7 553 }
ashleymills 0:e979170e02e7 554
ashleymills 0:e979170e02e7 555 /* make q */
ashleymills 0:e979170e02e7 556 if (err == MP_OKAY) {
ashleymills 0:e979170e02e7 557 do {
ashleymills 0:e979170e02e7 558 err = rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */
ashleymills 0:e979170e02e7 559
ashleymills 0:e979170e02e7 560 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 561 err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q-1 */
ashleymills 0:e979170e02e7 562
ashleymills 0:e979170e02e7 563 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 564 err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(q-1, e) */
ashleymills 0:e979170e02e7 565 } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divdes q-1 */
ashleymills 0:e979170e02e7 566 }
ashleymills 0:e979170e02e7 567
ashleymills 0:e979170e02e7 568 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 569 err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);
ashleymills 0:e979170e02e7 570
ashleymills 0:e979170e02e7 571 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 572 err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
ashleymills 0:e979170e02e7 573
ashleymills 0:e979170e02e7 574 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 575 err = mp_sub_d(&p, 1, &tmp2); /* tmp2 = p-1 */
ashleymills 0:e979170e02e7 576
ashleymills 0:e979170e02e7 577 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 578 err = mp_lcm(&tmp1, &tmp2, &tmp1); /* tmp1 = lcm(p-1, q-1),last loop */
ashleymills 0:e979170e02e7 579
ashleymills 0:e979170e02e7 580 /* make key */
ashleymills 0:e979170e02e7 581 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 582 err = mp_set_int(&key->e, e); /* key->e = e */
ashleymills 0:e979170e02e7 583
ashleymills 0:e979170e02e7 584 if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */
ashleymills 0:e979170e02e7 585 err = mp_invmod(&key->e, &tmp1, &key->d);
ashleymills 0:e979170e02e7 586
ashleymills 0:e979170e02e7 587 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 588 err = mp_mul(&p, &q, &key->n); /* key->n = pq */
ashleymills 0:e979170e02e7 589
ashleymills 0:e979170e02e7 590 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 591 err = mp_sub_d(&p, 1, &tmp1);
ashleymills 0:e979170e02e7 592
ashleymills 0:e979170e02e7 593 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 594 err = mp_sub_d(&q, 1, &tmp2);
ashleymills 0:e979170e02e7 595
ashleymills 0:e979170e02e7 596 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 597 err = mp_mod(&key->d, &tmp1, &key->dP);
ashleymills 0:e979170e02e7 598
ashleymills 0:e979170e02e7 599 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 600 err = mp_mod(&key->d, &tmp2, &key->dQ);
ashleymills 0:e979170e02e7 601
ashleymills 0:e979170e02e7 602 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 603 err = mp_invmod(&q, &p, &key->u);
ashleymills 0:e979170e02e7 604
ashleymills 0:e979170e02e7 605 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 606 err = mp_copy(&p, &key->p);
ashleymills 0:e979170e02e7 607
ashleymills 0:e979170e02e7 608 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 609 err = mp_copy(&q, &key->q);
ashleymills 0:e979170e02e7 610
ashleymills 0:e979170e02e7 611 if (err == MP_OKAY)
ashleymills 0:e979170e02e7 612 key->type = RSA_PRIVATE;
ashleymills 0:e979170e02e7 613
ashleymills 0:e979170e02e7 614 mp_clear(&tmp3);
ashleymills 0:e979170e02e7 615 mp_clear(&tmp2);
ashleymills 0:e979170e02e7 616 mp_clear(&tmp1);
ashleymills 0:e979170e02e7 617 mp_clear(&q);
ashleymills 0:e979170e02e7 618 mp_clear(&p);
ashleymills 0:e979170e02e7 619
ashleymills 0:e979170e02e7 620 if (err != MP_OKAY) {
ashleymills 0:e979170e02e7 621 FreeRsaKey(key);
ashleymills 0:e979170e02e7 622 return err;
ashleymills 0:e979170e02e7 623 }
ashleymills 0:e979170e02e7 624
ashleymills 0:e979170e02e7 625 return 0;
ashleymills 0:e979170e02e7 626 }
ashleymills 0:e979170e02e7 627
ashleymills 0:e979170e02e7 628
ashleymills 0:e979170e02e7 629 #endif /* CYASSL_KEY_GEN */
ashleymills 0:e979170e02e7 630
ashleymills 0:e979170e02e7 631
ashleymills 0:e979170e02e7 632 #ifdef HAVE_CAVIUM
ashleymills 0:e979170e02e7 633
ashleymills 0:e979170e02e7 634 #include <cyassl/ctaocrypt/logging.h>
ashleymills 0:e979170e02e7 635 #include "cavium_common.h"
ashleymills 0:e979170e02e7 636
ashleymills 0:e979170e02e7 637 /* Initiliaze RSA for use with Nitrox device */
ashleymills 0:e979170e02e7 638 int RsaInitCavium(RsaKey* rsa, int devId)
ashleymills 0:e979170e02e7 639 {
ashleymills 0:e979170e02e7 640 if (rsa == NULL)
ashleymills 0:e979170e02e7 641 return -1;
ashleymills 0:e979170e02e7 642
ashleymills 0:e979170e02e7 643 if (CspAllocContext(CONTEXT_SSL, &rsa->contextHandle, devId) != 0)
ashleymills 0:e979170e02e7 644 return -1;
ashleymills 0:e979170e02e7 645
ashleymills 0:e979170e02e7 646 rsa->devId = devId;
ashleymills 0:e979170e02e7 647 rsa->magic = CYASSL_RSA_CAVIUM_MAGIC;
ashleymills 0:e979170e02e7 648
ashleymills 0:e979170e02e7 649 return 0;
ashleymills 0:e979170e02e7 650 }
ashleymills 0:e979170e02e7 651
ashleymills 0:e979170e02e7 652
ashleymills 0:e979170e02e7 653 /* Free RSA from use with Nitrox device */
ashleymills 0:e979170e02e7 654 void RsaFreeCavium(RsaKey* rsa)
ashleymills 0:e979170e02e7 655 {
ashleymills 0:e979170e02e7 656 if (rsa == NULL)
ashleymills 0:e979170e02e7 657 return;
ashleymills 0:e979170e02e7 658
ashleymills 0:e979170e02e7 659 CspFreeContext(CONTEXT_SSL, rsa->contextHandle, rsa->devId);
ashleymills 0:e979170e02e7 660 rsa->magic = 0;
ashleymills 0:e979170e02e7 661 }
ashleymills 0:e979170e02e7 662
ashleymills 0:e979170e02e7 663
ashleymills 0:e979170e02e7 664 /* Initialize cavium RSA key */
ashleymills 0:e979170e02e7 665 static void InitCaviumRsaKey(RsaKey* key, void* heap)
ashleymills 0:e979170e02e7 666 {
ashleymills 0:e979170e02e7 667 if (key == NULL)
ashleymills 0:e979170e02e7 668 return;
ashleymills 0:e979170e02e7 669
ashleymills 0:e979170e02e7 670 key->heap = heap;
ashleymills 0:e979170e02e7 671 key->type = -1; /* don't know yet */
ashleymills 0:e979170e02e7 672
ashleymills 0:e979170e02e7 673 key->c_n = NULL;
ashleymills 0:e979170e02e7 674 key->c_e = NULL;
ashleymills 0:e979170e02e7 675 key->c_d = NULL;
ashleymills 0:e979170e02e7 676 key->c_p = NULL;
ashleymills 0:e979170e02e7 677 key->c_q = NULL;
ashleymills 0:e979170e02e7 678 key->c_dP = NULL;
ashleymills 0:e979170e02e7 679 key->c_dQ = NULL;
ashleymills 0:e979170e02e7 680 key->c_u = NULL;
ashleymills 0:e979170e02e7 681
ashleymills 0:e979170e02e7 682 key->c_nSz = 0;
ashleymills 0:e979170e02e7 683 key->c_eSz = 0;
ashleymills 0:e979170e02e7 684 key->c_dSz = 0;
ashleymills 0:e979170e02e7 685 key->c_pSz = 0;
ashleymills 0:e979170e02e7 686 key->c_qSz = 0;
ashleymills 0:e979170e02e7 687 key->c_dP_Sz = 0;
ashleymills 0:e979170e02e7 688 key->c_dQ_Sz = 0;
ashleymills 0:e979170e02e7 689 key->c_uSz = 0;
ashleymills 0:e979170e02e7 690 }
ashleymills 0:e979170e02e7 691
ashleymills 0:e979170e02e7 692
ashleymills 0:e979170e02e7 693 /* Free cavium RSA key */
ashleymills 0:e979170e02e7 694 static void FreeCaviumRsaKey(RsaKey* key)
ashleymills 0:e979170e02e7 695 {
ashleymills 0:e979170e02e7 696 if (key == NULL)
ashleymills 0:e979170e02e7 697 return;
ashleymills 0:e979170e02e7 698
ashleymills 0:e979170e02e7 699 XFREE(key->c_n, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
ashleymills 0:e979170e02e7 700 XFREE(key->c_e, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
ashleymills 0:e979170e02e7 701 XFREE(key->c_d, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
ashleymills 0:e979170e02e7 702 XFREE(key->c_p, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
ashleymills 0:e979170e02e7 703 XFREE(key->c_q, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
ashleymills 0:e979170e02e7 704 XFREE(key->c_dP, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
ashleymills 0:e979170e02e7 705 XFREE(key->c_dQ, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
ashleymills 0:e979170e02e7 706 XFREE(key->c_u, key->heap, DYNAMIC_TYPE_CAVIUM_TMP);
ashleymills 0:e979170e02e7 707
ashleymills 0:e979170e02e7 708 InitCaviumRsaKey(key, key->heap); /* reset pointers */
ashleymills 0:e979170e02e7 709 }
ashleymills 0:e979170e02e7 710
ashleymills 0:e979170e02e7 711
ashleymills 0:e979170e02e7 712 static int CaviumRsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
ashleymills 0:e979170e02e7 713 word32 outLen, RsaKey* key)
ashleymills 0:e979170e02e7 714 {
ashleymills 0:e979170e02e7 715 word32 requestId;
ashleymills 0:e979170e02e7 716 word32 ret;
ashleymills 0:e979170e02e7 717
ashleymills 0:e979170e02e7 718 if (key == NULL || in == NULL || out == NULL || outLen < (word32)key->c_nSz)
ashleymills 0:e979170e02e7 719 return -1;
ashleymills 0:e979170e02e7 720
ashleymills 0:e979170e02e7 721 ret = CspPkcs1v15Enc(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_eSz,
ashleymills 0:e979170e02e7 722 (word16)inLen, key->c_n, key->c_e, (byte*)in, out,
ashleymills 0:e979170e02e7 723 &requestId, key->devId);
ashleymills 0:e979170e02e7 724 if (ret != 0) {
ashleymills 0:e979170e02e7 725 CYASSL_MSG("Cavium Enc BT2 failed");
ashleymills 0:e979170e02e7 726 return -1;
ashleymills 0:e979170e02e7 727 }
ashleymills 0:e979170e02e7 728 return key->c_nSz;
ashleymills 0:e979170e02e7 729 }
ashleymills 0:e979170e02e7 730
ashleymills 0:e979170e02e7 731
ashleymills 0:e979170e02e7 732 static INLINE void ato16(const byte* c, word16* u16)
ashleymills 0:e979170e02e7 733 {
ashleymills 0:e979170e02e7 734 *u16 = (c[0] << 8) | (c[1]);
ashleymills 0:e979170e02e7 735 }
ashleymills 0:e979170e02e7 736
ashleymills 0:e979170e02e7 737
ashleymills 0:e979170e02e7 738 static int CaviumRsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
ashleymills 0:e979170e02e7 739 word32 outLen, RsaKey* key)
ashleymills 0:e979170e02e7 740 {
ashleymills 0:e979170e02e7 741 word32 requestId;
ashleymills 0:e979170e02e7 742 word32 ret;
ashleymills 0:e979170e02e7 743 word16 outSz = (word16)outLen;
ashleymills 0:e979170e02e7 744
ashleymills 0:e979170e02e7 745 if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz)
ashleymills 0:e979170e02e7 746 return -1;
ashleymills 0:e979170e02e7 747
ashleymills 0:e979170e02e7 748 ret = CspPkcs1v15CrtDec(CAVIUM_BLOCKING, BT2, key->c_nSz, key->c_q,
ashleymills 0:e979170e02e7 749 key->c_dQ, key->c_p, key->c_dP, key->c_u,
ashleymills 0:e979170e02e7 750 (byte*)in, &outSz, out, &requestId, key->devId);
ashleymills 0:e979170e02e7 751 if (ret != 0) {
ashleymills 0:e979170e02e7 752 CYASSL_MSG("Cavium CRT Dec BT2 failed");
ashleymills 0:e979170e02e7 753 return -1;
ashleymills 0:e979170e02e7 754 }
ashleymills 0:e979170e02e7 755 ato16((const byte*)&outSz, &outSz);
ashleymills 0:e979170e02e7 756
ashleymills 0:e979170e02e7 757 return outSz;
ashleymills 0:e979170e02e7 758 }
ashleymills 0:e979170e02e7 759
ashleymills 0:e979170e02e7 760
ashleymills 0:e979170e02e7 761 static int CaviumRsaSSL_Sign(const byte* in, word32 inLen, byte* out,
ashleymills 0:e979170e02e7 762 word32 outLen, RsaKey* key)
ashleymills 0:e979170e02e7 763 {
ashleymills 0:e979170e02e7 764 word32 requestId;
ashleymills 0:e979170e02e7 765 word32 ret;
ashleymills 0:e979170e02e7 766
ashleymills 0:e979170e02e7 767 if (key == NULL || in == NULL || out == NULL || inLen == 0 || outLen <
ashleymills 0:e979170e02e7 768 (word32)key->c_nSz)
ashleymills 0:e979170e02e7 769 return -1;
ashleymills 0:e979170e02e7 770
ashleymills 0:e979170e02e7 771 ret = CspPkcs1v15CrtEnc(CAVIUM_BLOCKING, BT1, key->c_nSz, (word16)inLen,
ashleymills 0:e979170e02e7 772 key->c_q, key->c_dQ, key->c_p, key->c_dP, key->c_u,
ashleymills 0:e979170e02e7 773 (byte*)in, out, &requestId, key->devId);
ashleymills 0:e979170e02e7 774 if (ret != 0) {
ashleymills 0:e979170e02e7 775 CYASSL_MSG("Cavium CRT Enc BT1 failed");
ashleymills 0:e979170e02e7 776 return -1;
ashleymills 0:e979170e02e7 777 }
ashleymills 0:e979170e02e7 778 return key->c_nSz;
ashleymills 0:e979170e02e7 779 }
ashleymills 0:e979170e02e7 780
ashleymills 0:e979170e02e7 781
ashleymills 0:e979170e02e7 782 static int CaviumRsaSSL_Verify(const byte* in, word32 inLen, byte* out,
ashleymills 0:e979170e02e7 783 word32 outLen, RsaKey* key)
ashleymills 0:e979170e02e7 784 {
ashleymills 0:e979170e02e7 785 word32 requestId;
ashleymills 0:e979170e02e7 786 word32 ret;
ashleymills 0:e979170e02e7 787 word16 outSz = (word16)outLen;
ashleymills 0:e979170e02e7 788
ashleymills 0:e979170e02e7 789 if (key == NULL || in == NULL || out == NULL || inLen != (word32)key->c_nSz)
ashleymills 0:e979170e02e7 790 return -1;
ashleymills 0:e979170e02e7 791
ashleymills 0:e979170e02e7 792 ret = CspPkcs1v15Dec(CAVIUM_BLOCKING, BT1, key->c_nSz, key->c_eSz,
ashleymills 0:e979170e02e7 793 key->c_n, key->c_e, (byte*)in, &outSz, out,
ashleymills 0:e979170e02e7 794 &requestId, key->devId);
ashleymills 0:e979170e02e7 795 if (ret != 0) {
ashleymills 0:e979170e02e7 796 CYASSL_MSG("Cavium Dec BT1 failed");
ashleymills 0:e979170e02e7 797 return -1;
ashleymills 0:e979170e02e7 798 }
ashleymills 0:e979170e02e7 799 outSz = ntohs(outSz);
ashleymills 0:e979170e02e7 800
ashleymills 0:e979170e02e7 801 return outSz;
ashleymills 0:e979170e02e7 802 }
ashleymills 0:e979170e02e7 803
ashleymills 0:e979170e02e7 804
ashleymills 0:e979170e02e7 805 #endif /* HAVE_CAVIUM */
ashleymills 0:e979170e02e7 806
ashleymills 0:e979170e02e7 807 #endif /* NO_RSA */