A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.

Dependents:   HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL

Committer:
Mike Fiore
Date:
Mon Mar 23 16:51:07 2015 -0500
Revision:
6:cf58d49e1a86
Parent:
0:b86d15c6ba29
fix whitespace in sha512.c

Who changed what in which revision?

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