wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Committer:
wolfSSL
Date:
Tue May 30 01:44:10 2017 +0000
Revision:
11:cee25a834751
wolfSSL 3.11.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 11:cee25a834751 1 /* rsa.c
wolfSSL 11:cee25a834751 2 *
wolfSSL 11:cee25a834751 3 * Copyright (C) 2006-2016 wolfSSL Inc.
wolfSSL 11:cee25a834751 4 *
wolfSSL 11:cee25a834751 5 * This file is part of wolfSSL.
wolfSSL 11:cee25a834751 6 *
wolfSSL 11:cee25a834751 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 11:cee25a834751 8 * it under the terms of the GNU General Public License as published by
wolfSSL 11:cee25a834751 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 11:cee25a834751 10 * (at your option) any later version.
wolfSSL 11:cee25a834751 11 *
wolfSSL 11:cee25a834751 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 11:cee25a834751 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 11:cee25a834751 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 11:cee25a834751 15 * GNU General Public License for more details.
wolfSSL 11:cee25a834751 16 *
wolfSSL 11:cee25a834751 17 * You should have received a copy of the GNU General Public License
wolfSSL 11:cee25a834751 18 * along with this program; if not, write to the Free Software
wolfSSL 11:cee25a834751 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 11:cee25a834751 20 */
wolfSSL 11:cee25a834751 21
wolfSSL 11:cee25a834751 22
wolfSSL 11:cee25a834751 23 #ifdef HAVE_CONFIG_H
wolfSSL 11:cee25a834751 24 #include <config.h>
wolfSSL 11:cee25a834751 25 #endif
wolfSSL 11:cee25a834751 26
wolfSSL 11:cee25a834751 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 11:cee25a834751 28
wolfSSL 11:cee25a834751 29 #ifndef NO_RSA
wolfSSL 11:cee25a834751 30
wolfSSL 11:cee25a834751 31 #include <wolfssl/wolfcrypt/rsa.h>
wolfSSL 11:cee25a834751 32
wolfSSL 11:cee25a834751 33 /*
wolfSSL 11:cee25a834751 34 Possible RSA enable options:
wolfSSL 11:cee25a834751 35 * NO_RSA: Overall control of RSA default: on (not defined)
wolfSSL 11:cee25a834751 36 * WC_RSA_BLINDING: Uses Blinding w/ Private Ops default: off
wolfSSL 11:cee25a834751 37 Note: slower by ~20%
wolfSSL 11:cee25a834751 38 * WOLFSSL_KEY_GEN: Allows Private Key Generation default: off
wolfSSL 11:cee25a834751 39 * RSA_LOW_MEM: NON CRT Private Operations, less memory default: off
wolfSSL 11:cee25a834751 40 * WC_NO_RSA_OAEP: Disables RSA OAEP padding default: on (not defined)
wolfSSL 11:cee25a834751 41
wolfSSL 11:cee25a834751 42 */
wolfSSL 11:cee25a834751 43
wolfSSL 11:cee25a834751 44 /*
wolfSSL 11:cee25a834751 45 RSA Key Size Configuration:
wolfSSL 11:cee25a834751 46 * FP_MAX_BITS: With USE_FAST_MATH only default: 4096
wolfSSL 11:cee25a834751 47 If USE_FAST_MATH then use this to override default.
wolfSSL 11:cee25a834751 48 Value is key size * 2. Example: RSA 3072 = 6144
wolfSSL 11:cee25a834751 49 */
wolfSSL 11:cee25a834751 50
wolfSSL 11:cee25a834751 51
wolfSSL 11:cee25a834751 52 #ifdef HAVE_FIPS
wolfSSL 11:cee25a834751 53 int wc_InitRsaKey(RsaKey* key, void* ptr)
wolfSSL 11:cee25a834751 54 {
wolfSSL 11:cee25a834751 55 return InitRsaKey_fips(key, ptr);
wolfSSL 11:cee25a834751 56 }
wolfSSL 11:cee25a834751 57
wolfSSL 11:cee25a834751 58 int wc_InitRsaKey_ex(RsaKey* key, void* ptr, int devId)
wolfSSL 11:cee25a834751 59 {
wolfSSL 11:cee25a834751 60 (void)devId;
wolfSSL 11:cee25a834751 61 return InitRsaKey_fips(key, ptr);
wolfSSL 11:cee25a834751 62 }
wolfSSL 11:cee25a834751 63
wolfSSL 11:cee25a834751 64 int wc_FreeRsaKey(RsaKey* key)
wolfSSL 11:cee25a834751 65 {
wolfSSL 11:cee25a834751 66 return FreeRsaKey_fips(key);
wolfSSL 11:cee25a834751 67 }
wolfSSL 11:cee25a834751 68
wolfSSL 11:cee25a834751 69
wolfSSL 11:cee25a834751 70 int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 71 word32 outLen, RsaKey* key, WC_RNG* rng)
wolfSSL 11:cee25a834751 72 {
wolfSSL 11:cee25a834751 73 return RsaPublicEncrypt_fips(in, inLen, out, outLen, key, rng);
wolfSSL 11:cee25a834751 74 }
wolfSSL 11:cee25a834751 75
wolfSSL 11:cee25a834751 76
wolfSSL 11:cee25a834751 77 int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out,
wolfSSL 11:cee25a834751 78 RsaKey* key)
wolfSSL 11:cee25a834751 79 {
wolfSSL 11:cee25a834751 80 return RsaPrivateDecryptInline_fips(in, inLen, out, key);
wolfSSL 11:cee25a834751 81 }
wolfSSL 11:cee25a834751 82
wolfSSL 11:cee25a834751 83
wolfSSL 11:cee25a834751 84 int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 85 word32 outLen, RsaKey* key)
wolfSSL 11:cee25a834751 86 {
wolfSSL 11:cee25a834751 87 return RsaPrivateDecrypt_fips(in, inLen, out, outLen, key);
wolfSSL 11:cee25a834751 88 }
wolfSSL 11:cee25a834751 89
wolfSSL 11:cee25a834751 90
wolfSSL 11:cee25a834751 91 int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 92 word32 outLen, RsaKey* key, WC_RNG* rng)
wolfSSL 11:cee25a834751 93 {
wolfSSL 11:cee25a834751 94 return RsaSSL_Sign_fips(in, inLen, out, outLen, key, rng);
wolfSSL 11:cee25a834751 95 }
wolfSSL 11:cee25a834751 96
wolfSSL 11:cee25a834751 97
wolfSSL 11:cee25a834751 98 int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
wolfSSL 11:cee25a834751 99 {
wolfSSL 11:cee25a834751 100 return RsaSSL_VerifyInline_fips(in, inLen, out, key);
wolfSSL 11:cee25a834751 101 }
wolfSSL 11:cee25a834751 102
wolfSSL 11:cee25a834751 103
wolfSSL 11:cee25a834751 104 int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 105 word32 outLen, RsaKey* key)
wolfSSL 11:cee25a834751 106 {
wolfSSL 11:cee25a834751 107 return RsaSSL_Verify_fips(in, inLen, out, outLen, key);
wolfSSL 11:cee25a834751 108 }
wolfSSL 11:cee25a834751 109
wolfSSL 11:cee25a834751 110
wolfSSL 11:cee25a834751 111 int wc_RsaEncryptSize(RsaKey* key)
wolfSSL 11:cee25a834751 112 {
wolfSSL 11:cee25a834751 113 return RsaEncryptSize_fips(key);
wolfSSL 11:cee25a834751 114 }
wolfSSL 11:cee25a834751 115
wolfSSL 11:cee25a834751 116
wolfSSL 11:cee25a834751 117 int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b,
wolfSSL 11:cee25a834751 118 word32* bSz)
wolfSSL 11:cee25a834751 119 {
wolfSSL 11:cee25a834751 120 /* not specified as fips so not needing _fips */
wolfSSL 11:cee25a834751 121 return RsaFlattenPublicKey(key, a, aSz, b, bSz);
wolfSSL 11:cee25a834751 122 }
wolfSSL 11:cee25a834751 123 #ifdef WOLFSSL_KEY_GEN
wolfSSL 11:cee25a834751 124 int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
wolfSSL 11:cee25a834751 125 {
wolfSSL 11:cee25a834751 126 return MakeRsaKey(key, size, e, rng);
wolfSSL 11:cee25a834751 127 }
wolfSSL 11:cee25a834751 128 #endif
wolfSSL 11:cee25a834751 129
wolfSSL 11:cee25a834751 130
wolfSSL 11:cee25a834751 131 /* these are functions in asn and are routed to wolfssl/wolfcrypt/asn.c
wolfSSL 11:cee25a834751 132 * wc_RsaPrivateKeyDecode
wolfSSL 11:cee25a834751 133 * wc_RsaPublicKeyDecode
wolfSSL 11:cee25a834751 134 */
wolfSSL 11:cee25a834751 135
wolfSSL 11:cee25a834751 136 #else /* else build without fips */
wolfSSL 11:cee25a834751 137
wolfSSL 11:cee25a834751 138 #include <wolfssl/wolfcrypt/random.h>
wolfSSL 11:cee25a834751 139 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 11:cee25a834751 140 #include <wolfssl/wolfcrypt/logging.h>
wolfSSL 11:cee25a834751 141 #ifdef NO_INLINE
wolfSSL 11:cee25a834751 142 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 11:cee25a834751 143 #else
wolfSSL 11:cee25a834751 144 #define WOLFSSL_MISC_INCLUDED
wolfSSL 11:cee25a834751 145 #include <wolfcrypt/src/misc.c>
wolfSSL 11:cee25a834751 146 #endif
wolfSSL 11:cee25a834751 147
wolfSSL 11:cee25a834751 148 #define ERROR_OUT(x) { ret = (x); goto done;}
wolfSSL 11:cee25a834751 149
wolfSSL 11:cee25a834751 150
wolfSSL 11:cee25a834751 151 enum {
wolfSSL 11:cee25a834751 152 RSA_STATE_NONE = 0,
wolfSSL 11:cee25a834751 153
wolfSSL 11:cee25a834751 154 RSA_STATE_ENCRYPT_PAD,
wolfSSL 11:cee25a834751 155 RSA_STATE_ENCRYPT_EXPTMOD,
wolfSSL 11:cee25a834751 156 RSA_STATE_ENCRYPT_RES,
wolfSSL 11:cee25a834751 157
wolfSSL 11:cee25a834751 158 RSA_STATE_DECRYPT_EXPTMOD,
wolfSSL 11:cee25a834751 159 RSA_STATE_DECRYPT_UNPAD,
wolfSSL 11:cee25a834751 160 RSA_STATE_DECRYPT_RES,
wolfSSL 11:cee25a834751 161 };
wolfSSL 11:cee25a834751 162
wolfSSL 11:cee25a834751 163 static void wc_RsaCleanup(RsaKey* key)
wolfSSL 11:cee25a834751 164 {
wolfSSL 11:cee25a834751 165 if (key && key->data) {
wolfSSL 11:cee25a834751 166 /* make sure any allocated memory is free'd */
wolfSSL 11:cee25a834751 167 if (key->dataIsAlloc) {
wolfSSL 11:cee25a834751 168 if (key->type == RSA_PRIVATE_DECRYPT ||
wolfSSL 11:cee25a834751 169 key->type == RSA_PRIVATE_ENCRYPT) {
wolfSSL 11:cee25a834751 170 ForceZero(key->data, key->dataLen);
wolfSSL 11:cee25a834751 171 }
wolfSSL 11:cee25a834751 172 XFREE(key->data, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);
wolfSSL 11:cee25a834751 173 key->dataIsAlloc = 0;
wolfSSL 11:cee25a834751 174 }
wolfSSL 11:cee25a834751 175 key->data = NULL;
wolfSSL 11:cee25a834751 176 key->dataLen = 0;
wolfSSL 11:cee25a834751 177 }
wolfSSL 11:cee25a834751 178 }
wolfSSL 11:cee25a834751 179
wolfSSL 11:cee25a834751 180 int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId)
wolfSSL 11:cee25a834751 181 {
wolfSSL 11:cee25a834751 182 int ret = 0;
wolfSSL 11:cee25a834751 183
wolfSSL 11:cee25a834751 184 if (key == NULL) {
wolfSSL 11:cee25a834751 185 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 186 }
wolfSSL 11:cee25a834751 187
wolfSSL 11:cee25a834751 188 key->type = RSA_TYPE_UNKNOWN;
wolfSSL 11:cee25a834751 189 key->state = RSA_STATE_NONE;
wolfSSL 11:cee25a834751 190 key->heap = heap;
wolfSSL 11:cee25a834751 191 key->data = NULL;
wolfSSL 11:cee25a834751 192 key->dataLen = 0;
wolfSSL 11:cee25a834751 193 key->dataIsAlloc = 0;
wolfSSL 11:cee25a834751 194 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 195 key->rng = NULL;
wolfSSL 11:cee25a834751 196 #endif
wolfSSL 11:cee25a834751 197
wolfSSL 11:cee25a834751 198 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
wolfSSL 11:cee25a834751 199 /* handle as async */
wolfSSL 11:cee25a834751 200 ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA,
wolfSSL 11:cee25a834751 201 key->heap, devId);
wolfSSL 11:cee25a834751 202 #ifdef WOLFSSL_CERT_GEN
wolfSSL 11:cee25a834751 203 XMEMSET(&key->certSignCtx, 0, sizeof(CertSignCtx));
wolfSSL 11:cee25a834751 204 #endif
wolfSSL 11:cee25a834751 205 #else
wolfSSL 11:cee25a834751 206 (void)devId;
wolfSSL 11:cee25a834751 207 #endif
wolfSSL 11:cee25a834751 208
wolfSSL 11:cee25a834751 209 mp_init(&key->n);
wolfSSL 11:cee25a834751 210 mp_init(&key->e);
wolfSSL 11:cee25a834751 211 mp_init(&key->d);
wolfSSL 11:cee25a834751 212 mp_init(&key->p);
wolfSSL 11:cee25a834751 213 mp_init(&key->q);
wolfSSL 11:cee25a834751 214 mp_init(&key->dP);
wolfSSL 11:cee25a834751 215 mp_init(&key->dQ);
wolfSSL 11:cee25a834751 216 mp_init(&key->u);
wolfSSL 11:cee25a834751 217
wolfSSL 11:cee25a834751 218 return ret;
wolfSSL 11:cee25a834751 219 }
wolfSSL 11:cee25a834751 220
wolfSSL 11:cee25a834751 221 int wc_InitRsaKey(RsaKey* key, void* heap)
wolfSSL 11:cee25a834751 222 {
wolfSSL 11:cee25a834751 223 return wc_InitRsaKey_ex(key, heap, INVALID_DEVID);
wolfSSL 11:cee25a834751 224 }
wolfSSL 11:cee25a834751 225
wolfSSL 11:cee25a834751 226 int wc_FreeRsaKey(RsaKey* key)
wolfSSL 11:cee25a834751 227 {
wolfSSL 11:cee25a834751 228 int ret = 0;
wolfSSL 11:cee25a834751 229
wolfSSL 11:cee25a834751 230 if (key == NULL) {
wolfSSL 11:cee25a834751 231 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 232 }
wolfSSL 11:cee25a834751 233
wolfSSL 11:cee25a834751 234 wc_RsaCleanup(key);
wolfSSL 11:cee25a834751 235
wolfSSL 11:cee25a834751 236 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
wolfSSL 11:cee25a834751 237 wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA);
wolfSSL 11:cee25a834751 238 #endif
wolfSSL 11:cee25a834751 239
wolfSSL 11:cee25a834751 240 if (key->type == RSA_PRIVATE) {
wolfSSL 11:cee25a834751 241 mp_forcezero(&key->u);
wolfSSL 11:cee25a834751 242 mp_forcezero(&key->dQ);
wolfSSL 11:cee25a834751 243 mp_forcezero(&key->dP);
wolfSSL 11:cee25a834751 244 mp_forcezero(&key->q);
wolfSSL 11:cee25a834751 245 mp_forcezero(&key->p);
wolfSSL 11:cee25a834751 246 mp_forcezero(&key->d);
wolfSSL 11:cee25a834751 247 }
wolfSSL 11:cee25a834751 248 /* private part */
wolfSSL 11:cee25a834751 249 mp_clear(&key->u);
wolfSSL 11:cee25a834751 250 mp_clear(&key->dQ);
wolfSSL 11:cee25a834751 251 mp_clear(&key->dP);
wolfSSL 11:cee25a834751 252 mp_clear(&key->q);
wolfSSL 11:cee25a834751 253 mp_clear(&key->p);
wolfSSL 11:cee25a834751 254 mp_clear(&key->d);
wolfSSL 11:cee25a834751 255
wolfSSL 11:cee25a834751 256 /* public part */
wolfSSL 11:cee25a834751 257 mp_clear(&key->e);
wolfSSL 11:cee25a834751 258 mp_clear(&key->n);
wolfSSL 11:cee25a834751 259
wolfSSL 11:cee25a834751 260 return ret;
wolfSSL 11:cee25a834751 261 }
wolfSSL 11:cee25a834751 262
wolfSSL 11:cee25a834751 263
wolfSSL 11:cee25a834751 264 #ifndef WC_NO_RSA_OAEP
wolfSSL 11:cee25a834751 265 /* Uses MGF1 standard as a mask generation function
wolfSSL 11:cee25a834751 266 hType: hash type used
wolfSSL 11:cee25a834751 267 seed: seed to use for generating mask
wolfSSL 11:cee25a834751 268 seedSz: size of seed buffer
wolfSSL 11:cee25a834751 269 out: mask output after generation
wolfSSL 11:cee25a834751 270 outSz: size of output buffer
wolfSSL 11:cee25a834751 271 */
wolfSSL 11:cee25a834751 272 static int RsaMGF1(enum wc_HashType hType, byte* seed, word32 seedSz,
wolfSSL 11:cee25a834751 273 byte* out, word32 outSz, void* heap)
wolfSSL 11:cee25a834751 274 {
wolfSSL 11:cee25a834751 275 byte* tmp;
wolfSSL 11:cee25a834751 276 /* needs to be large enough for seed size plus counter(4) */
wolfSSL 11:cee25a834751 277 byte tmpA[WC_MAX_DIGEST_SIZE + 4];
wolfSSL 11:cee25a834751 278 byte tmpF; /* 1 if dynamic memory needs freed */
wolfSSL 11:cee25a834751 279 word32 tmpSz;
wolfSSL 11:cee25a834751 280 int hLen;
wolfSSL 11:cee25a834751 281 int ret;
wolfSSL 11:cee25a834751 282 word32 counter;
wolfSSL 11:cee25a834751 283 word32 idx;
wolfSSL 11:cee25a834751 284 hLen = wc_HashGetDigestSize(hType);
wolfSSL 11:cee25a834751 285 counter = 0;
wolfSSL 11:cee25a834751 286 idx = 0;
wolfSSL 11:cee25a834751 287
wolfSSL 11:cee25a834751 288 (void)heap;
wolfSSL 11:cee25a834751 289
wolfSSL 11:cee25a834751 290 /* check error return of wc_HashGetDigestSize */
wolfSSL 11:cee25a834751 291 if (hLen < 0) {
wolfSSL 11:cee25a834751 292 return hLen;
wolfSSL 11:cee25a834751 293 }
wolfSSL 11:cee25a834751 294
wolfSSL 11:cee25a834751 295 /* if tmp is not large enough than use some dynamic memory */
wolfSSL 11:cee25a834751 296 if ((seedSz + 4) > sizeof(tmpA) || (word32)hLen > sizeof(tmpA)) {
wolfSSL 11:cee25a834751 297 /* find largest amount of memory needed which will be the max of
wolfSSL 11:cee25a834751 298 * hLen and (seedSz + 4) since tmp is used to store the hash digest */
wolfSSL 11:cee25a834751 299 tmpSz = ((seedSz + 4) > (word32)hLen)? seedSz + 4: (word32)hLen;
wolfSSL 11:cee25a834751 300 tmp = (byte*)XMALLOC(tmpSz, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 301 if (tmp == NULL) {
wolfSSL 11:cee25a834751 302 return MEMORY_E;
wolfSSL 11:cee25a834751 303 }
wolfSSL 11:cee25a834751 304 tmpF = 1; /* make sure to free memory when done */
wolfSSL 11:cee25a834751 305 }
wolfSSL 11:cee25a834751 306 else {
wolfSSL 11:cee25a834751 307 /* use array on the stack */
wolfSSL 11:cee25a834751 308 tmpSz = sizeof(tmpA);
wolfSSL 11:cee25a834751 309 tmp = tmpA;
wolfSSL 11:cee25a834751 310 tmpF = 0; /* no need to free memory at end */
wolfSSL 11:cee25a834751 311 }
wolfSSL 11:cee25a834751 312
wolfSSL 11:cee25a834751 313 do {
wolfSSL 11:cee25a834751 314 int i = 0;
wolfSSL 11:cee25a834751 315 XMEMCPY(tmp, seed, seedSz);
wolfSSL 11:cee25a834751 316
wolfSSL 11:cee25a834751 317 /* counter to byte array appended to tmp */
wolfSSL 11:cee25a834751 318 tmp[seedSz] = (counter >> 24) & 0xFF;
wolfSSL 11:cee25a834751 319 tmp[seedSz + 1] = (counter >> 16) & 0xFF;
wolfSSL 11:cee25a834751 320 tmp[seedSz + 2] = (counter >> 8) & 0xFF;
wolfSSL 11:cee25a834751 321 tmp[seedSz + 3] = (counter) & 0xFF;
wolfSSL 11:cee25a834751 322
wolfSSL 11:cee25a834751 323 /* hash and append to existing output */
wolfSSL 11:cee25a834751 324 if ((ret = wc_Hash(hType, tmp, (seedSz + 4), tmp, tmpSz)) != 0) {
wolfSSL 11:cee25a834751 325 /* check for if dynamic memory was needed, then free */
wolfSSL 11:cee25a834751 326 if (tmpF) {
wolfSSL 11:cee25a834751 327 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 328 }
wolfSSL 11:cee25a834751 329 return ret;
wolfSSL 11:cee25a834751 330 }
wolfSSL 11:cee25a834751 331
wolfSSL 11:cee25a834751 332 for (i = 0; i < hLen && idx < outSz; i++) {
wolfSSL 11:cee25a834751 333 out[idx++] = tmp[i];
wolfSSL 11:cee25a834751 334 }
wolfSSL 11:cee25a834751 335 counter++;
wolfSSL 11:cee25a834751 336 } while (idx < outSz);
wolfSSL 11:cee25a834751 337
wolfSSL 11:cee25a834751 338 /* check for if dynamic memory was needed, then free */
wolfSSL 11:cee25a834751 339 if (tmpF) {
wolfSSL 11:cee25a834751 340 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 341 }
wolfSSL 11:cee25a834751 342
wolfSSL 11:cee25a834751 343 return 0;
wolfSSL 11:cee25a834751 344 }
wolfSSL 11:cee25a834751 345
wolfSSL 11:cee25a834751 346 /* helper function to direct which mask generation function is used
wolfSSL 11:cee25a834751 347 switeched on type input
wolfSSL 11:cee25a834751 348 */
wolfSSL 11:cee25a834751 349 static int RsaMGF(int type, byte* seed, word32 seedSz, byte* out,
wolfSSL 11:cee25a834751 350 word32 outSz, void* heap)
wolfSSL 11:cee25a834751 351 {
wolfSSL 11:cee25a834751 352 int ret;
wolfSSL 11:cee25a834751 353
wolfSSL 11:cee25a834751 354 switch(type) {
wolfSSL 11:cee25a834751 355 #ifndef NO_SHA
wolfSSL 11:cee25a834751 356 case WC_MGF1SHA1:
wolfSSL 11:cee25a834751 357 ret = RsaMGF1(WC_HASH_TYPE_SHA, seed, seedSz, out, outSz, heap);
wolfSSL 11:cee25a834751 358 break;
wolfSSL 11:cee25a834751 359 #endif
wolfSSL 11:cee25a834751 360 #ifndef NO_SHA256
wolfSSL 11:cee25a834751 361 #ifdef WOLFSSL_SHA224
wolfSSL 11:cee25a834751 362 case WC_MGF1SHA224:
wolfSSL 11:cee25a834751 363 ret = RsaMGF1(WC_HASH_TYPE_SHA224, seed, seedSz, out, outSz, heap);
wolfSSL 11:cee25a834751 364 break;
wolfSSL 11:cee25a834751 365 #endif
wolfSSL 11:cee25a834751 366 case WC_MGF1SHA256:
wolfSSL 11:cee25a834751 367 ret = RsaMGF1(WC_HASH_TYPE_SHA256, seed, seedSz, out, outSz, heap);
wolfSSL 11:cee25a834751 368 break;
wolfSSL 11:cee25a834751 369 #endif
wolfSSL 11:cee25a834751 370 #ifdef WOLFSSL_SHA512
wolfSSL 11:cee25a834751 371 #ifdef WOLFSSL_SHA384
wolfSSL 11:cee25a834751 372 case WC_MGF1SHA384:
wolfSSL 11:cee25a834751 373 ret = RsaMGF1(WC_HASH_TYPE_SHA384, seed, seedSz, out, outSz, heap);
wolfSSL 11:cee25a834751 374 break;
wolfSSL 11:cee25a834751 375 #endif
wolfSSL 11:cee25a834751 376 case WC_MGF1SHA512:
wolfSSL 11:cee25a834751 377 ret = RsaMGF1(WC_HASH_TYPE_SHA512, seed, seedSz, out, outSz, heap);
wolfSSL 11:cee25a834751 378 break;
wolfSSL 11:cee25a834751 379 #endif
wolfSSL 11:cee25a834751 380 default:
wolfSSL 11:cee25a834751 381 WOLFSSL_MSG("Unknown MGF type: check build options");
wolfSSL 11:cee25a834751 382 ret = BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 383 }
wolfSSL 11:cee25a834751 384
wolfSSL 11:cee25a834751 385 /* in case of default avoid unused warning */
wolfSSL 11:cee25a834751 386 (void)seed;
wolfSSL 11:cee25a834751 387 (void)seedSz;
wolfSSL 11:cee25a834751 388 (void)out;
wolfSSL 11:cee25a834751 389 (void)outSz;
wolfSSL 11:cee25a834751 390 (void)heap;
wolfSSL 11:cee25a834751 391
wolfSSL 11:cee25a834751 392 return ret;
wolfSSL 11:cee25a834751 393 }
wolfSSL 11:cee25a834751 394 #endif /* !WC_NO_RSA_OAEP */
wolfSSL 11:cee25a834751 395
wolfSSL 11:cee25a834751 396
wolfSSL 11:cee25a834751 397 /* Padding */
wolfSSL 11:cee25a834751 398 #ifndef WC_NO_RSA_OAEP
wolfSSL 11:cee25a834751 399 static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
wolfSSL 11:cee25a834751 400 word32 pkcsBlockLen, byte padValue, WC_RNG* rng,
wolfSSL 11:cee25a834751 401 enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen,
wolfSSL 11:cee25a834751 402 void* heap)
wolfSSL 11:cee25a834751 403 {
wolfSSL 11:cee25a834751 404 int ret;
wolfSSL 11:cee25a834751 405 int hLen;
wolfSSL 11:cee25a834751 406 int psLen;
wolfSSL 11:cee25a834751 407 int i;
wolfSSL 11:cee25a834751 408 word32 idx;
wolfSSL 11:cee25a834751 409
wolfSSL 11:cee25a834751 410 byte* dbMask;
wolfSSL 11:cee25a834751 411
wolfSSL 11:cee25a834751 412 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 413 byte* lHash = NULL;
wolfSSL 11:cee25a834751 414 byte* seed = NULL;
wolfSSL 11:cee25a834751 415 #else
wolfSSL 11:cee25a834751 416 /* must be large enough to contain largest hash */
wolfSSL 11:cee25a834751 417 byte lHash[WC_MAX_DIGEST_SIZE];
wolfSSL 11:cee25a834751 418 byte seed[ WC_MAX_DIGEST_SIZE];
wolfSSL 11:cee25a834751 419 #endif
wolfSSL 11:cee25a834751 420
wolfSSL 11:cee25a834751 421 /* no label is allowed, but catch if no label provided and length > 0 */
wolfSSL 11:cee25a834751 422 if (optLabel == NULL && labelLen > 0) {
wolfSSL 11:cee25a834751 423 return BUFFER_E;
wolfSSL 11:cee25a834751 424 }
wolfSSL 11:cee25a834751 425
wolfSSL 11:cee25a834751 426 /* limit of label is the same as limit of hash function which is massive */
wolfSSL 11:cee25a834751 427 hLen = wc_HashGetDigestSize(hType);
wolfSSL 11:cee25a834751 428 if (hLen < 0) {
wolfSSL 11:cee25a834751 429 return hLen;
wolfSSL 11:cee25a834751 430 }
wolfSSL 11:cee25a834751 431
wolfSSL 11:cee25a834751 432 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 433 lHash = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 434 if (lHash == NULL) {
wolfSSL 11:cee25a834751 435 return MEMORY_E;
wolfSSL 11:cee25a834751 436 }
wolfSSL 11:cee25a834751 437 seed = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 438 if (seed == NULL) {
wolfSSL 11:cee25a834751 439 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 440 return MEMORY_E;
wolfSSL 11:cee25a834751 441 }
wolfSSL 11:cee25a834751 442 #else
wolfSSL 11:cee25a834751 443 /* hLen should never be larger than lHash since size is max digest size,
wolfSSL 11:cee25a834751 444 but check before blindly calling wc_Hash */
wolfSSL 11:cee25a834751 445 if ((word32)hLen > sizeof(lHash)) {
wolfSSL 11:cee25a834751 446 WOLFSSL_MSG("OAEP lHash to small for digest!!");
wolfSSL 11:cee25a834751 447 return MEMORY_E;
wolfSSL 11:cee25a834751 448 }
wolfSSL 11:cee25a834751 449 #endif
wolfSSL 11:cee25a834751 450
wolfSSL 11:cee25a834751 451 if ((ret = wc_Hash(hType, optLabel, labelLen, lHash, hLen)) != 0) {
wolfSSL 11:cee25a834751 452 WOLFSSL_MSG("OAEP hash type possibly not supported or lHash to small");
wolfSSL 11:cee25a834751 453 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 454 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 455 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 456 #endif
wolfSSL 11:cee25a834751 457 return ret;
wolfSSL 11:cee25a834751 458 }
wolfSSL 11:cee25a834751 459
wolfSSL 11:cee25a834751 460 /* handles check of location for idx as well as psLen, cast to int to check
wolfSSL 11:cee25a834751 461 for pkcsBlockLen(k) - 2 * hLen - 2 being negative
wolfSSL 11:cee25a834751 462 This check is similar to decryption where k > 2 * hLen + 2 as msg
wolfSSL 11:cee25a834751 463 size aproaches 0. In decryption if k is less than or equal -- then there
wolfSSL 11:cee25a834751 464 is no possible room for msg.
wolfSSL 11:cee25a834751 465 k = RSA key size
wolfSSL 11:cee25a834751 466 hLen = hash digest size -- will always be >= 0 at this point
wolfSSL 11:cee25a834751 467 */
wolfSSL 11:cee25a834751 468 if ((word32)(2 * hLen + 2) > pkcsBlockLen) {
wolfSSL 11:cee25a834751 469 WOLFSSL_MSG("OAEP pad error hash to big for RSA key size");
wolfSSL 11:cee25a834751 470 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 471 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 472 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 473 #endif
wolfSSL 11:cee25a834751 474 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 475 }
wolfSSL 11:cee25a834751 476
wolfSSL 11:cee25a834751 477 if (inputLen > (pkcsBlockLen - 2 * hLen - 2)) {
wolfSSL 11:cee25a834751 478 WOLFSSL_MSG("OAEP pad error message too long");
wolfSSL 11:cee25a834751 479 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 480 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 481 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 482 #endif
wolfSSL 11:cee25a834751 483 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 484 }
wolfSSL 11:cee25a834751 485
wolfSSL 11:cee25a834751 486 /* concatenate lHash || PS || 0x01 || msg */
wolfSSL 11:cee25a834751 487 idx = pkcsBlockLen - 1 - inputLen;
wolfSSL 11:cee25a834751 488 psLen = pkcsBlockLen - inputLen - 2 * hLen - 2;
wolfSSL 11:cee25a834751 489 if (pkcsBlockLen < inputLen) { /*make sure not writing over end of buffer */
wolfSSL 11:cee25a834751 490 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 491 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 492 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 493 #endif
wolfSSL 11:cee25a834751 494 return BUFFER_E;
wolfSSL 11:cee25a834751 495 }
wolfSSL 11:cee25a834751 496 XMEMCPY(pkcsBlock + (pkcsBlockLen - inputLen), input, inputLen);
wolfSSL 11:cee25a834751 497 pkcsBlock[idx--] = 0x01; /* PS and M separator */
wolfSSL 11:cee25a834751 498 while (psLen > 0 && idx > 0) {
wolfSSL 11:cee25a834751 499 pkcsBlock[idx--] = 0x00;
wolfSSL 11:cee25a834751 500 psLen--;
wolfSSL 11:cee25a834751 501 }
wolfSSL 11:cee25a834751 502
wolfSSL 11:cee25a834751 503 idx = idx - hLen + 1;
wolfSSL 11:cee25a834751 504 XMEMCPY(pkcsBlock + idx, lHash, hLen);
wolfSSL 11:cee25a834751 505
wolfSSL 11:cee25a834751 506 /* generate random seed */
wolfSSL 11:cee25a834751 507 if ((ret = wc_RNG_GenerateBlock(rng, seed, hLen)) != 0) {
wolfSSL 11:cee25a834751 508 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 509 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 510 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 511 #endif
wolfSSL 11:cee25a834751 512 return ret;
wolfSSL 11:cee25a834751 513 }
wolfSSL 11:cee25a834751 514
wolfSSL 11:cee25a834751 515 /* create maskedDB from dbMask */
wolfSSL 11:cee25a834751 516 dbMask = (byte*)XMALLOC(pkcsBlockLen - hLen - 1, heap, DYNAMIC_TYPE_RSA);
wolfSSL 11:cee25a834751 517 if (dbMask == NULL) {
wolfSSL 11:cee25a834751 518 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 519 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 520 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 521 #endif
wolfSSL 11:cee25a834751 522 return MEMORY_E;
wolfSSL 11:cee25a834751 523 }
wolfSSL 11:cee25a834751 524 XMEMSET(dbMask, 0, pkcsBlockLen - hLen - 1); /* help static analyzer */
wolfSSL 11:cee25a834751 525
wolfSSL 11:cee25a834751 526 ret = RsaMGF(mgf, seed, hLen, dbMask, pkcsBlockLen - hLen - 1, heap);
wolfSSL 11:cee25a834751 527 if (ret != 0) {
wolfSSL 11:cee25a834751 528 XFREE(dbMask, heap, DYNAMIC_TYPE_RSA);
wolfSSL 11:cee25a834751 529 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 530 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 531 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 532 #endif
wolfSSL 11:cee25a834751 533 return ret;
wolfSSL 11:cee25a834751 534 }
wolfSSL 11:cee25a834751 535
wolfSSL 11:cee25a834751 536 i = 0;
wolfSSL 11:cee25a834751 537 idx = hLen + 1;
wolfSSL 11:cee25a834751 538 while (idx < pkcsBlockLen && (word32)i < (pkcsBlockLen - hLen -1)) {
wolfSSL 11:cee25a834751 539 pkcsBlock[idx] = dbMask[i++] ^ pkcsBlock[idx];
wolfSSL 11:cee25a834751 540 idx++;
wolfSSL 11:cee25a834751 541 }
wolfSSL 11:cee25a834751 542 XFREE(dbMask, heap, DYNAMIC_TYPE_RSA);
wolfSSL 11:cee25a834751 543
wolfSSL 11:cee25a834751 544
wolfSSL 11:cee25a834751 545 /* create maskedSeed from seedMask */
wolfSSL 11:cee25a834751 546 idx = 0;
wolfSSL 11:cee25a834751 547 pkcsBlock[idx++] = 0x00;
wolfSSL 11:cee25a834751 548 /* create seedMask inline */
wolfSSL 11:cee25a834751 549 if ((ret = RsaMGF(mgf, pkcsBlock + hLen + 1, pkcsBlockLen - hLen - 1,
wolfSSL 11:cee25a834751 550 pkcsBlock + 1, hLen, heap)) != 0) {
wolfSSL 11:cee25a834751 551 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 552 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 553 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 554 #endif
wolfSSL 11:cee25a834751 555 return ret;
wolfSSL 11:cee25a834751 556 }
wolfSSL 11:cee25a834751 557
wolfSSL 11:cee25a834751 558 /* xor created seedMask with seed to make maskedSeed */
wolfSSL 11:cee25a834751 559 i = 0;
wolfSSL 11:cee25a834751 560 while (idx < (word32)(hLen + 1) && i < hLen) {
wolfSSL 11:cee25a834751 561 pkcsBlock[idx] = pkcsBlock[idx] ^ seed[i++];
wolfSSL 11:cee25a834751 562 idx++;
wolfSSL 11:cee25a834751 563 }
wolfSSL 11:cee25a834751 564
wolfSSL 11:cee25a834751 565 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 11:cee25a834751 566 XFREE(lHash, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 567 XFREE(seed, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 568 #endif
wolfSSL 11:cee25a834751 569 (void)padValue;
wolfSSL 11:cee25a834751 570
wolfSSL 11:cee25a834751 571 return 0;
wolfSSL 11:cee25a834751 572 }
wolfSSL 11:cee25a834751 573 #endif /* !WC_NO_RSA_OAEP */
wolfSSL 11:cee25a834751 574
wolfSSL 11:cee25a834751 575
wolfSSL 11:cee25a834751 576 static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock,
wolfSSL 11:cee25a834751 577 word32 pkcsBlockLen, byte padValue, WC_RNG* rng)
wolfSSL 11:cee25a834751 578 {
wolfSSL 11:cee25a834751 579 if (input == NULL || inputLen == 0 || pkcsBlock == NULL ||
wolfSSL 11:cee25a834751 580 pkcsBlockLen == 0) {
wolfSSL 11:cee25a834751 581 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 582 }
wolfSSL 11:cee25a834751 583
wolfSSL 11:cee25a834751 584 pkcsBlock[0] = 0x0; /* set first byte to zero and advance */
wolfSSL 11:cee25a834751 585 pkcsBlock++; pkcsBlockLen--;
wolfSSL 11:cee25a834751 586 pkcsBlock[0] = padValue; /* insert padValue */
wolfSSL 11:cee25a834751 587
wolfSSL 11:cee25a834751 588 if (padValue == RSA_BLOCK_TYPE_1) {
wolfSSL 11:cee25a834751 589 if (pkcsBlockLen < inputLen + 2) {
wolfSSL 11:cee25a834751 590 WOLFSSL_MSG("RsaPad error, invalid length");
wolfSSL 11:cee25a834751 591 return RSA_PAD_E;
wolfSSL 11:cee25a834751 592 }
wolfSSL 11:cee25a834751 593
wolfSSL 11:cee25a834751 594 /* pad with 0xff bytes */
wolfSSL 11:cee25a834751 595 XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
wolfSSL 11:cee25a834751 596 }
wolfSSL 11:cee25a834751 597 else {
wolfSSL 11:cee25a834751 598 /* pad with non-zero random bytes */
wolfSSL 11:cee25a834751 599 word32 padLen, i;
wolfSSL 11:cee25a834751 600 int ret;
wolfSSL 11:cee25a834751 601
wolfSSL 11:cee25a834751 602 if (pkcsBlockLen < inputLen + 1) {
wolfSSL 11:cee25a834751 603 WOLFSSL_MSG("RsaPad error, invalid length");
wolfSSL 11:cee25a834751 604 return RSA_PAD_E;
wolfSSL 11:cee25a834751 605 }
wolfSSL 11:cee25a834751 606
wolfSSL 11:cee25a834751 607 padLen = pkcsBlockLen - inputLen - 1;
wolfSSL 11:cee25a834751 608 ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen);
wolfSSL 11:cee25a834751 609 if (ret != 0) {
wolfSSL 11:cee25a834751 610 return ret;
wolfSSL 11:cee25a834751 611 }
wolfSSL 11:cee25a834751 612
wolfSSL 11:cee25a834751 613 /* remove zeros */
wolfSSL 11:cee25a834751 614 for (i = 1; i < padLen; i++) {
wolfSSL 11:cee25a834751 615 if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
wolfSSL 11:cee25a834751 616 }
wolfSSL 11:cee25a834751 617 }
wolfSSL 11:cee25a834751 618
wolfSSL 11:cee25a834751 619 pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */
wolfSSL 11:cee25a834751 620 XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
wolfSSL 11:cee25a834751 621
wolfSSL 11:cee25a834751 622 return 0;
wolfSSL 11:cee25a834751 623 }
wolfSSL 11:cee25a834751 624
wolfSSL 11:cee25a834751 625 /* helper function to direct which padding is used */
wolfSSL 11:cee25a834751 626 static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock,
wolfSSL 11:cee25a834751 627 word32 pkcsBlockLen, byte padValue, WC_RNG* rng, int padType,
wolfSSL 11:cee25a834751 628 enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen,
wolfSSL 11:cee25a834751 629 void* heap)
wolfSSL 11:cee25a834751 630 {
wolfSSL 11:cee25a834751 631 int ret;
wolfSSL 11:cee25a834751 632
wolfSSL 11:cee25a834751 633 switch (padType)
wolfSSL 11:cee25a834751 634 {
wolfSSL 11:cee25a834751 635 case WC_RSA_PKCSV15_PAD:
wolfSSL 11:cee25a834751 636 /*WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding");*/
wolfSSL 11:cee25a834751 637 ret = RsaPad(input, inputLen, pkcsBlock, pkcsBlockLen,
wolfSSL 11:cee25a834751 638 padValue, rng);
wolfSSL 11:cee25a834751 639 break;
wolfSSL 11:cee25a834751 640
wolfSSL 11:cee25a834751 641 #ifndef WC_NO_RSA_OAEP
wolfSSL 11:cee25a834751 642 case WC_RSA_OAEP_PAD:
wolfSSL 11:cee25a834751 643 WOLFSSL_MSG("wolfSSL Using RSA OAEP padding");
wolfSSL 11:cee25a834751 644 ret = RsaPad_OAEP(input, inputLen, pkcsBlock, pkcsBlockLen,
wolfSSL 11:cee25a834751 645 padValue, rng, hType, mgf, optLabel, labelLen, heap);
wolfSSL 11:cee25a834751 646 break;
wolfSSL 11:cee25a834751 647 #endif
wolfSSL 11:cee25a834751 648 default:
wolfSSL 11:cee25a834751 649 WOLFSSL_MSG("Unknown RSA Pad Type");
wolfSSL 11:cee25a834751 650 ret = RSA_PAD_E;
wolfSSL 11:cee25a834751 651 }
wolfSSL 11:cee25a834751 652
wolfSSL 11:cee25a834751 653 /* silence warning if not used with padding scheme */
wolfSSL 11:cee25a834751 654 (void)hType;
wolfSSL 11:cee25a834751 655 (void)mgf;
wolfSSL 11:cee25a834751 656 (void)optLabel;
wolfSSL 11:cee25a834751 657 (void)labelLen;
wolfSSL 11:cee25a834751 658 (void)heap;
wolfSSL 11:cee25a834751 659
wolfSSL 11:cee25a834751 660 return ret;
wolfSSL 11:cee25a834751 661 }
wolfSSL 11:cee25a834751 662
wolfSSL 11:cee25a834751 663
wolfSSL 11:cee25a834751 664 /* UnPadding */
wolfSSL 11:cee25a834751 665 #ifndef WC_NO_RSA_OAEP
wolfSSL 11:cee25a834751 666 /* UnPad plaintext, set start to *output, return length of plaintext,
wolfSSL 11:cee25a834751 667 * < 0 on error */
wolfSSL 11:cee25a834751 668 static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
wolfSSL 11:cee25a834751 669 byte **output, enum wc_HashType hType, int mgf,
wolfSSL 11:cee25a834751 670 byte* optLabel, word32 labelLen, void* heap)
wolfSSL 11:cee25a834751 671 {
wolfSSL 11:cee25a834751 672 int hLen;
wolfSSL 11:cee25a834751 673 int ret;
wolfSSL 11:cee25a834751 674 byte h[WC_MAX_DIGEST_SIZE]; /* max digest size */
wolfSSL 11:cee25a834751 675 byte* tmp;
wolfSSL 11:cee25a834751 676 word32 idx;
wolfSSL 11:cee25a834751 677
wolfSSL 11:cee25a834751 678 /* no label is allowed, but catch if no label provided and length > 0 */
wolfSSL 11:cee25a834751 679 if (optLabel == NULL && labelLen > 0) {
wolfSSL 11:cee25a834751 680 return BUFFER_E;
wolfSSL 11:cee25a834751 681 }
wolfSSL 11:cee25a834751 682
wolfSSL 11:cee25a834751 683 hLen = wc_HashGetDigestSize(hType);
wolfSSL 11:cee25a834751 684 if ((hLen < 0) || (pkcsBlockLen < (2 * (word32)hLen + 2))) {
wolfSSL 11:cee25a834751 685 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 686 }
wolfSSL 11:cee25a834751 687
wolfSSL 11:cee25a834751 688 tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 689 if (tmp == NULL) {
wolfSSL 11:cee25a834751 690 return MEMORY_E;
wolfSSL 11:cee25a834751 691 }
wolfSSL 11:cee25a834751 692 XMEMSET(tmp, 0, pkcsBlockLen);
wolfSSL 11:cee25a834751 693
wolfSSL 11:cee25a834751 694 /* find seedMask value */
wolfSSL 11:cee25a834751 695 if ((ret = RsaMGF(mgf, (byte*)(pkcsBlock + (hLen + 1)),
wolfSSL 11:cee25a834751 696 pkcsBlockLen - hLen - 1, tmp, hLen, heap)) != 0) {
wolfSSL 11:cee25a834751 697 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 698 return ret;
wolfSSL 11:cee25a834751 699 }
wolfSSL 11:cee25a834751 700
wolfSSL 11:cee25a834751 701 /* xor seedMask value with maskedSeed to get seed value */
wolfSSL 11:cee25a834751 702 for (idx = 0; idx < (word32)hLen; idx++) {
wolfSSL 11:cee25a834751 703 tmp[idx] = tmp[idx] ^ pkcsBlock[1 + idx];
wolfSSL 11:cee25a834751 704 }
wolfSSL 11:cee25a834751 705
wolfSSL 11:cee25a834751 706 /* get dbMask value */
wolfSSL 11:cee25a834751 707 if ((ret = RsaMGF(mgf, tmp, hLen, tmp + hLen,
wolfSSL 11:cee25a834751 708 pkcsBlockLen - hLen - 1, heap)) != 0) {
wolfSSL 11:cee25a834751 709 XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 710 return ret;
wolfSSL 11:cee25a834751 711 }
wolfSSL 11:cee25a834751 712
wolfSSL 11:cee25a834751 713 /* get DB value by doing maskedDB xor dbMask */
wolfSSL 11:cee25a834751 714 for (idx = 0; idx < (pkcsBlockLen - hLen - 1); idx++) {
wolfSSL 11:cee25a834751 715 pkcsBlock[hLen + 1 + idx] = pkcsBlock[hLen + 1 + idx] ^ tmp[idx + hLen];
wolfSSL 11:cee25a834751 716 }
wolfSSL 11:cee25a834751 717
wolfSSL 11:cee25a834751 718 /* done with use of tmp buffer */
wolfSSL 11:cee25a834751 719 XFREE(tmp, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 11:cee25a834751 720
wolfSSL 11:cee25a834751 721 /* advance idx to index of PS and msg separator, account for PS size of 0*/
wolfSSL 11:cee25a834751 722 idx = hLen + 1 + hLen;
wolfSSL 11:cee25a834751 723 while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;}
wolfSSL 11:cee25a834751 724
wolfSSL 11:cee25a834751 725 /* create hash of label for comparision with hash sent */
wolfSSL 11:cee25a834751 726 if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) {
wolfSSL 11:cee25a834751 727 return ret;
wolfSSL 11:cee25a834751 728 }
wolfSSL 11:cee25a834751 729
wolfSSL 11:cee25a834751 730 /* say no to chosen ciphertext attack.
wolfSSL 11:cee25a834751 731 Comparison of lHash, Y, and separator value needs to all happen in
wolfSSL 11:cee25a834751 732 constant time.
wolfSSL 11:cee25a834751 733 Attackers should not be able to get error condition from the timing of
wolfSSL 11:cee25a834751 734 these checks.
wolfSSL 11:cee25a834751 735 */
wolfSSL 11:cee25a834751 736 ret = 0;
wolfSSL 11:cee25a834751 737 ret |= ConstantCompare(pkcsBlock + hLen + 1, h, hLen);
wolfSSL 11:cee25a834751 738 ret += pkcsBlock[idx++] ^ 0x01; /* separator value is 0x01 */
wolfSSL 11:cee25a834751 739 ret += pkcsBlock[0] ^ 0x00; /* Y, the first value, should be 0 */
wolfSSL 11:cee25a834751 740
wolfSSL 11:cee25a834751 741 if (ret != 0) {
wolfSSL 11:cee25a834751 742 return BAD_PADDING_E;
wolfSSL 11:cee25a834751 743 }
wolfSSL 11:cee25a834751 744
wolfSSL 11:cee25a834751 745 /* adjust pointer to correct location in array and return size of M */
wolfSSL 11:cee25a834751 746 *output = (byte*)(pkcsBlock + idx);
wolfSSL 11:cee25a834751 747 return pkcsBlockLen - idx;
wolfSSL 11:cee25a834751 748 }
wolfSSL 11:cee25a834751 749 #endif /* WC_NO_RSA_OAEP */
wolfSSL 11:cee25a834751 750
wolfSSL 11:cee25a834751 751
wolfSSL 11:cee25a834751 752 /* UnPad plaintext, set start to *output, return length of plaintext,
wolfSSL 11:cee25a834751 753 * < 0 on error */
wolfSSL 11:cee25a834751 754 static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
wolfSSL 11:cee25a834751 755 byte **output, byte padValue)
wolfSSL 11:cee25a834751 756 {
wolfSSL 11:cee25a834751 757 word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0;
wolfSSL 11:cee25a834751 758 word32 invalid = 0;
wolfSSL 11:cee25a834751 759 word32 i = 1;
wolfSSL 11:cee25a834751 760 word32 outputLen;
wolfSSL 11:cee25a834751 761
wolfSSL 11:cee25a834751 762 if (output == NULL || pkcsBlockLen == 0) {
wolfSSL 11:cee25a834751 763 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 764 }
wolfSSL 11:cee25a834751 765
wolfSSL 11:cee25a834751 766 if (pkcsBlock[0] != 0x0) { /* skip past zero */
wolfSSL 11:cee25a834751 767 invalid = 1;
wolfSSL 11:cee25a834751 768 }
wolfSSL 11:cee25a834751 769 pkcsBlock++; pkcsBlockLen--;
wolfSSL 11:cee25a834751 770
wolfSSL 11:cee25a834751 771 /* Require block type padValue */
wolfSSL 11:cee25a834751 772 invalid = (pkcsBlock[0] != padValue) || invalid;
wolfSSL 11:cee25a834751 773
wolfSSL 11:cee25a834751 774 /* verify the padding until we find the separator */
wolfSSL 11:cee25a834751 775 if (padValue == RSA_BLOCK_TYPE_1) {
wolfSSL 11:cee25a834751 776 while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
wolfSSL 11:cee25a834751 777 }
wolfSSL 11:cee25a834751 778 else {
wolfSSL 11:cee25a834751 779 while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
wolfSSL 11:cee25a834751 780 }
wolfSSL 11:cee25a834751 781
wolfSSL 11:cee25a834751 782 if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
wolfSSL 11:cee25a834751 783 WOLFSSL_MSG("RsaUnPad error, bad formatting");
wolfSSL 11:cee25a834751 784 return RSA_PAD_E;
wolfSSL 11:cee25a834751 785 }
wolfSSL 11:cee25a834751 786
wolfSSL 11:cee25a834751 787 outputLen = pkcsBlockLen - i;
wolfSSL 11:cee25a834751 788 invalid = (outputLen > maxOutputLen) || invalid;
wolfSSL 11:cee25a834751 789
wolfSSL 11:cee25a834751 790 if (invalid) {
wolfSSL 11:cee25a834751 791 WOLFSSL_MSG("RsaUnPad error, invalid formatting");
wolfSSL 11:cee25a834751 792 return RSA_PAD_E;
wolfSSL 11:cee25a834751 793 }
wolfSSL 11:cee25a834751 794
wolfSSL 11:cee25a834751 795 *output = (byte *)(pkcsBlock + i);
wolfSSL 11:cee25a834751 796 return outputLen;
wolfSSL 11:cee25a834751 797 }
wolfSSL 11:cee25a834751 798
wolfSSL 11:cee25a834751 799 /* helper function to direct unpadding */
wolfSSL 11:cee25a834751 800 static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out,
wolfSSL 11:cee25a834751 801 byte padValue, int padType, enum wc_HashType hType,
wolfSSL 11:cee25a834751 802 int mgf, byte* optLabel, word32 labelLen, void* heap)
wolfSSL 11:cee25a834751 803 {
wolfSSL 11:cee25a834751 804 int ret;
wolfSSL 11:cee25a834751 805
wolfSSL 11:cee25a834751 806 switch (padType) {
wolfSSL 11:cee25a834751 807 case WC_RSA_PKCSV15_PAD:
wolfSSL 11:cee25a834751 808 /*WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 un-padding");*/
wolfSSL 11:cee25a834751 809 ret = RsaUnPad(pkcsBlock, pkcsBlockLen, out, padValue);
wolfSSL 11:cee25a834751 810 break;
wolfSSL 11:cee25a834751 811
wolfSSL 11:cee25a834751 812 #ifndef WC_NO_RSA_OAEP
wolfSSL 11:cee25a834751 813 case WC_RSA_OAEP_PAD:
wolfSSL 11:cee25a834751 814 WOLFSSL_MSG("wolfSSL Using RSA OAEP un-padding");
wolfSSL 11:cee25a834751 815 ret = RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out,
wolfSSL 11:cee25a834751 816 hType, mgf, optLabel, labelLen, heap);
wolfSSL 11:cee25a834751 817 break;
wolfSSL 11:cee25a834751 818 #endif
wolfSSL 11:cee25a834751 819
wolfSSL 11:cee25a834751 820 default:
wolfSSL 11:cee25a834751 821 WOLFSSL_MSG("Unknown RSA UnPad Type");
wolfSSL 11:cee25a834751 822 ret = RSA_PAD_E;
wolfSSL 11:cee25a834751 823 }
wolfSSL 11:cee25a834751 824
wolfSSL 11:cee25a834751 825 /* silence warning if not used with padding scheme */
wolfSSL 11:cee25a834751 826 (void)hType;
wolfSSL 11:cee25a834751 827 (void)mgf;
wolfSSL 11:cee25a834751 828 (void)optLabel;
wolfSSL 11:cee25a834751 829 (void)labelLen;
wolfSSL 11:cee25a834751 830 (void)heap;
wolfSSL 11:cee25a834751 831
wolfSSL 11:cee25a834751 832 return ret;
wolfSSL 11:cee25a834751 833 }
wolfSSL 11:cee25a834751 834
wolfSSL 11:cee25a834751 835 static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 836 word32* outLen, int type, RsaKey* key, WC_RNG* rng)
wolfSSL 11:cee25a834751 837 {
wolfSSL 11:cee25a834751 838 mp_int tmp;
wolfSSL 11:cee25a834751 839 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 840 mp_int rnd, rndi;
wolfSSL 11:cee25a834751 841 #endif
wolfSSL 11:cee25a834751 842 int ret = 0;
wolfSSL 11:cee25a834751 843 word32 keyLen, len;
wolfSSL 11:cee25a834751 844
wolfSSL 11:cee25a834751 845 (void)rng;
wolfSSL 11:cee25a834751 846
wolfSSL 11:cee25a834751 847 if (mp_init(&tmp) != MP_OKAY)
wolfSSL 11:cee25a834751 848 return MP_INIT_E;
wolfSSL 11:cee25a834751 849
wolfSSL 11:cee25a834751 850 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 851 if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
wolfSSL 11:cee25a834751 852 if (mp_init_multi(&rnd, &rndi, NULL, NULL, NULL, NULL) != MP_OKAY) {
wolfSSL 11:cee25a834751 853 mp_clear(&tmp);
wolfSSL 11:cee25a834751 854 return MP_INIT_E;
wolfSSL 11:cee25a834751 855 }
wolfSSL 11:cee25a834751 856 }
wolfSSL 11:cee25a834751 857 #endif
wolfSSL 11:cee25a834751 858
wolfSSL 11:cee25a834751 859 if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
wolfSSL 11:cee25a834751 860 ERROR_OUT(MP_READ_E);
wolfSSL 11:cee25a834751 861
wolfSSL 11:cee25a834751 862 switch(type) {
wolfSSL 11:cee25a834751 863 case RSA_PRIVATE_DECRYPT:
wolfSSL 11:cee25a834751 864 case RSA_PRIVATE_ENCRYPT:
wolfSSL 11:cee25a834751 865 {
wolfSSL 11:cee25a834751 866 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 867 /* blind */
wolfSSL 11:cee25a834751 868 ret = mp_rand(&rnd, get_digit_count(&key->n), rng);
wolfSSL 11:cee25a834751 869 if (ret != MP_OKAY)
wolfSSL 11:cee25a834751 870 goto done;
wolfSSL 11:cee25a834751 871
wolfSSL 11:cee25a834751 872 /* rndi = 1/rnd mod n */
wolfSSL 11:cee25a834751 873 if (mp_invmod(&rnd, &key->n, &rndi) != MP_OKAY)
wolfSSL 11:cee25a834751 874 ERROR_OUT(MP_INVMOD_E);
wolfSSL 11:cee25a834751 875
wolfSSL 11:cee25a834751 876 /* rnd = rnd^e */
wolfSSL 11:cee25a834751 877 if (mp_exptmod(&rnd, &key->e, &key->n, &rnd) != MP_OKAY)
wolfSSL 11:cee25a834751 878 ERROR_OUT(MP_EXPTMOD_E);
wolfSSL 11:cee25a834751 879
wolfSSL 11:cee25a834751 880 /* tmp = tmp*rnd mod n */
wolfSSL 11:cee25a834751 881 if (mp_mulmod(&tmp, &rnd, &key->n, &tmp) != MP_OKAY)
wolfSSL 11:cee25a834751 882 ERROR_OUT(MP_MULMOD_E);
wolfSSL 11:cee25a834751 883 #endif /* WC_RSA_BLINGING */
wolfSSL 11:cee25a834751 884
wolfSSL 11:cee25a834751 885 #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */
wolfSSL 11:cee25a834751 886 if (mp_exptmod(&tmp, &key->d, &key->n, &tmp) != MP_OKAY)
wolfSSL 11:cee25a834751 887 ERROR_OUT(MP_EXPTMOD_E);
wolfSSL 11:cee25a834751 888 #else
wolfSSL 11:cee25a834751 889 /* Return 0 when cond is false and n when cond is true. */
wolfSSL 11:cee25a834751 890 #define COND_N(cond, n) ((0 - (cond)) & (n))
wolfSSL 11:cee25a834751 891 /* If ret has an error value return it otherwise if r is OK then return
wolfSSL 11:cee25a834751 892 * 0 otherwise return e.
wolfSSL 11:cee25a834751 893 */
wolfSSL 11:cee25a834751 894 #define RET_ERR(ret, r, e) \
wolfSSL 11:cee25a834751 895 ((ret) | (COND_N((ret) == 0, COND_N((r) != MP_OKAY, (e)))))
wolfSSL 11:cee25a834751 896
wolfSSL 11:cee25a834751 897 { /* tmpa/b scope */
wolfSSL 11:cee25a834751 898 mp_int tmpa, tmpb;
wolfSSL 11:cee25a834751 899 int r;
wolfSSL 11:cee25a834751 900
wolfSSL 11:cee25a834751 901 if (mp_init(&tmpa) != MP_OKAY)
wolfSSL 11:cee25a834751 902 ERROR_OUT(MP_INIT_E);
wolfSSL 11:cee25a834751 903
wolfSSL 11:cee25a834751 904 if (mp_init(&tmpb) != MP_OKAY) {
wolfSSL 11:cee25a834751 905 mp_clear(&tmpa);
wolfSSL 11:cee25a834751 906 ERROR_OUT(MP_INIT_E);
wolfSSL 11:cee25a834751 907 }
wolfSSL 11:cee25a834751 908
wolfSSL 11:cee25a834751 909 /* tmpa = tmp^dP mod p */
wolfSSL 11:cee25a834751 910 r = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa);
wolfSSL 11:cee25a834751 911 ret = RET_ERR(ret, r, MP_EXPTMOD_E);
wolfSSL 11:cee25a834751 912
wolfSSL 11:cee25a834751 913 /* tmpb = tmp^dQ mod q */
wolfSSL 11:cee25a834751 914 r = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb);
wolfSSL 11:cee25a834751 915 ret = RET_ERR(ret, r, MP_EXPTMOD_E);
wolfSSL 11:cee25a834751 916
wolfSSL 11:cee25a834751 917 /* tmp = (tmpa - tmpb) * qInv (mod p) */
wolfSSL 11:cee25a834751 918 r = mp_sub(&tmpa, &tmpb, &tmp);
wolfSSL 11:cee25a834751 919 ret = RET_ERR(ret, r, MP_SUB_E);
wolfSSL 11:cee25a834751 920
wolfSSL 11:cee25a834751 921 r = mp_mulmod(&tmp, &key->u, &key->p, &tmp);
wolfSSL 11:cee25a834751 922 ret = RET_ERR(ret, r, MP_MULMOD_E);
wolfSSL 11:cee25a834751 923
wolfSSL 11:cee25a834751 924 /* tmp = tmpb + q * tmp */
wolfSSL 11:cee25a834751 925 r = mp_mul(&tmp, &key->q, &tmp);
wolfSSL 11:cee25a834751 926 ret = RET_ERR(ret, r, MP_MUL_E);
wolfSSL 11:cee25a834751 927
wolfSSL 11:cee25a834751 928 r = mp_add(&tmp, &tmpb, &tmp);
wolfSSL 11:cee25a834751 929 ret = RET_ERR(ret, r, MP_ADD_E);
wolfSSL 11:cee25a834751 930
wolfSSL 11:cee25a834751 931 mp_clear(&tmpa);
wolfSSL 11:cee25a834751 932 mp_clear(&tmpb);
wolfSSL 11:cee25a834751 933
wolfSSL 11:cee25a834751 934 if (ret != 0) {
wolfSSL 11:cee25a834751 935 goto done;
wolfSSL 11:cee25a834751 936 }
wolfSSL 11:cee25a834751 937 #undef RET_ERR
wolfSSL 11:cee25a834751 938 #undef COND_N
wolfSSL 11:cee25a834751 939 } /* tmpa/b scope */
wolfSSL 11:cee25a834751 940 #endif /* RSA_LOW_MEM */
wolfSSL 11:cee25a834751 941
wolfSSL 11:cee25a834751 942 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 943 /* unblind */
wolfSSL 11:cee25a834751 944 if (mp_mulmod(&tmp, &rndi, &key->n, &tmp) != MP_OKAY)
wolfSSL 11:cee25a834751 945 ERROR_OUT(MP_MULMOD_E);
wolfSSL 11:cee25a834751 946 #endif /* WC_RSA_BLINDING */
wolfSSL 11:cee25a834751 947
wolfSSL 11:cee25a834751 948 break;
wolfSSL 11:cee25a834751 949 }
wolfSSL 11:cee25a834751 950 case RSA_PUBLIC_ENCRYPT:
wolfSSL 11:cee25a834751 951 case RSA_PUBLIC_DECRYPT:
wolfSSL 11:cee25a834751 952 if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
wolfSSL 11:cee25a834751 953 ERROR_OUT(MP_EXPTMOD_E);
wolfSSL 11:cee25a834751 954 break;
wolfSSL 11:cee25a834751 955 default:
wolfSSL 11:cee25a834751 956 ERROR_OUT(RSA_WRONG_TYPE_E);
wolfSSL 11:cee25a834751 957 }
wolfSSL 11:cee25a834751 958
wolfSSL 11:cee25a834751 959 keyLen = wc_RsaEncryptSize(key);
wolfSSL 11:cee25a834751 960 if (keyLen > *outLen) {
wolfSSL 11:cee25a834751 961 ERROR_OUT(RSA_BUFFER_E);
wolfSSL 11:cee25a834751 962 }
wolfSSL 11:cee25a834751 963
wolfSSL 11:cee25a834751 964 len = mp_unsigned_bin_size(&tmp);
wolfSSL 11:cee25a834751 965
wolfSSL 11:cee25a834751 966 /* pad front w/ zeros to match key length */
wolfSSL 11:cee25a834751 967 while (len < keyLen) {
wolfSSL 11:cee25a834751 968 *out++ = 0x00;
wolfSSL 11:cee25a834751 969 len++;
wolfSSL 11:cee25a834751 970 }
wolfSSL 11:cee25a834751 971
wolfSSL 11:cee25a834751 972 *outLen = keyLen;
wolfSSL 11:cee25a834751 973
wolfSSL 11:cee25a834751 974 /* convert */
wolfSSL 11:cee25a834751 975 if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
wolfSSL 11:cee25a834751 976 ERROR_OUT(MP_TO_E);
wolfSSL 11:cee25a834751 977
wolfSSL 11:cee25a834751 978 done:
wolfSSL 11:cee25a834751 979 mp_clear(&tmp);
wolfSSL 11:cee25a834751 980 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 981 if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
wolfSSL 11:cee25a834751 982 mp_clear(&rndi);
wolfSSL 11:cee25a834751 983 mp_clear(&rnd);
wolfSSL 11:cee25a834751 984 }
wolfSSL 11:cee25a834751 985 #endif
wolfSSL 11:cee25a834751 986 return ret;
wolfSSL 11:cee25a834751 987 }
wolfSSL 11:cee25a834751 988
wolfSSL 11:cee25a834751 989 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
wolfSSL 11:cee25a834751 990 static int wc_RsaFunctionAsync(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 991 word32* outLen, int type, RsaKey* key, WC_RNG* rng)
wolfSSL 11:cee25a834751 992 {
wolfSSL 11:cee25a834751 993 int ret = 0;
wolfSSL 11:cee25a834751 994
wolfSSL 11:cee25a834751 995 (void)rng;
wolfSSL 11:cee25a834751 996
wolfSSL 11:cee25a834751 997 #ifdef WOLFSSL_ASYNC_CRYPT_TEST
wolfSSL 11:cee25a834751 998 WC_ASYNC_TEST* testDev = &key->asyncDev.test;
wolfSSL 11:cee25a834751 999 if (testDev->type == ASYNC_TEST_NONE) {
wolfSSL 11:cee25a834751 1000 testDev->type = ASYNC_TEST_RSA_FUNC;
wolfSSL 11:cee25a834751 1001 testDev->rsaFunc.in = in;
wolfSSL 11:cee25a834751 1002 testDev->rsaFunc.inSz = inLen;
wolfSSL 11:cee25a834751 1003 testDev->rsaFunc.out = out;
wolfSSL 11:cee25a834751 1004 testDev->rsaFunc.outSz = outLen;
wolfSSL 11:cee25a834751 1005 testDev->rsaFunc.type = type;
wolfSSL 11:cee25a834751 1006 testDev->rsaFunc.key = key;
wolfSSL 11:cee25a834751 1007 testDev->rsaFunc.rng = rng;
wolfSSL 11:cee25a834751 1008 return WC_PENDING_E;
wolfSSL 11:cee25a834751 1009 }
wolfSSL 11:cee25a834751 1010 #endif /* WOLFSSL_ASYNC_CRYPT_TEST */
wolfSSL 11:cee25a834751 1011
wolfSSL 11:cee25a834751 1012 switch(type) {
wolfSSL 11:cee25a834751 1013 case RSA_PRIVATE_DECRYPT:
wolfSSL 11:cee25a834751 1014 case RSA_PRIVATE_ENCRYPT:
wolfSSL 11:cee25a834751 1015 #ifdef HAVE_CAVIUM
wolfSSL 11:cee25a834751 1016 ret = NitroxRsaExptMod(in, inLen,
wolfSSL 11:cee25a834751 1017 key->d.raw.buf, key->d.raw.len,
wolfSSL 11:cee25a834751 1018 key->n.raw.buf, key->n.raw.len,
wolfSSL 11:cee25a834751 1019 out, outLen, key);
wolfSSL 11:cee25a834751 1020 #elif defined(HAVE_INTEL_QA)
wolfSSL 11:cee25a834751 1021 #ifdef RSA_LOW_MEM
wolfSSL 11:cee25a834751 1022 ret = IntelQaRsaPrivate(&key->asyncDev, in, inLen,
wolfSSL 11:cee25a834751 1023 &key->d.raw, &key->n.raw,
wolfSSL 11:cee25a834751 1024 out, outLen);
wolfSSL 11:cee25a834751 1025 #else
wolfSSL 11:cee25a834751 1026 ret = IntelQaRsaCrtPrivate(&key->asyncDev, in, inLen,
wolfSSL 11:cee25a834751 1027 &key->p.raw, &key->q.raw,
wolfSSL 11:cee25a834751 1028 &key->dP.raw, &key->dQ.raw,
wolfSSL 11:cee25a834751 1029 &key->u.raw,
wolfSSL 11:cee25a834751 1030 out, outLen);
wolfSSL 11:cee25a834751 1031 #endif
wolfSSL 11:cee25a834751 1032 #else /* WOLFSSL_ASYNC_CRYPT_TEST */
wolfSSL 11:cee25a834751 1033 ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
wolfSSL 11:cee25a834751 1034 #endif
wolfSSL 11:cee25a834751 1035 break;
wolfSSL 11:cee25a834751 1036
wolfSSL 11:cee25a834751 1037 case RSA_PUBLIC_ENCRYPT:
wolfSSL 11:cee25a834751 1038 case RSA_PUBLIC_DECRYPT:
wolfSSL 11:cee25a834751 1039 #ifdef HAVE_CAVIUM
wolfSSL 11:cee25a834751 1040 ret = NitroxRsaExptMod(in, inLen,
wolfSSL 11:cee25a834751 1041 key->e.raw.buf, key->e.raw.len,
wolfSSL 11:cee25a834751 1042 key->n.raw.buf, key->n.raw.len,
wolfSSL 11:cee25a834751 1043 out, outLen, key);
wolfSSL 11:cee25a834751 1044 #elif defined(HAVE_INTEL_QA)
wolfSSL 11:cee25a834751 1045 ret = IntelQaRsaPublic(&key->asyncDev, in, inLen,
wolfSSL 11:cee25a834751 1046 &key->e.raw, &key->n.raw,
wolfSSL 11:cee25a834751 1047 out, outLen);
wolfSSL 11:cee25a834751 1048 #else /* WOLFSSL_ASYNC_CRYPT_TEST */
wolfSSL 11:cee25a834751 1049 ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
wolfSSL 11:cee25a834751 1050 #endif
wolfSSL 11:cee25a834751 1051 break;
wolfSSL 11:cee25a834751 1052
wolfSSL 11:cee25a834751 1053 default:
wolfSSL 11:cee25a834751 1054 ret = RSA_WRONG_TYPE_E;
wolfSSL 11:cee25a834751 1055 }
wolfSSL 11:cee25a834751 1056
wolfSSL 11:cee25a834751 1057 return ret;
wolfSSL 11:cee25a834751 1058 }
wolfSSL 11:cee25a834751 1059 #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_RSA */
wolfSSL 11:cee25a834751 1060
wolfSSL 11:cee25a834751 1061 int wc_RsaFunction(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 1062 word32* outLen, int type, RsaKey* key, WC_RNG* rng)
wolfSSL 11:cee25a834751 1063 {
wolfSSL 11:cee25a834751 1064 int ret;
wolfSSL 11:cee25a834751 1065
wolfSSL 11:cee25a834751 1066 if (key == NULL || in == NULL || inLen == 0 || out == NULL ||
wolfSSL 11:cee25a834751 1067 outLen == NULL || *outLen == 0 || type == RSA_TYPE_UNKNOWN) {
wolfSSL 11:cee25a834751 1068 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1069 }
wolfSSL 11:cee25a834751 1070
wolfSSL 11:cee25a834751 1071 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
wolfSSL 11:cee25a834751 1072 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
wolfSSL 11:cee25a834751 1073 key->n.raw.len > 0) {
wolfSSL 11:cee25a834751 1074 ret = wc_RsaFunctionAsync(in, inLen, out, outLen, type, key, rng);
wolfSSL 11:cee25a834751 1075 }
wolfSSL 11:cee25a834751 1076 else
wolfSSL 11:cee25a834751 1077 #endif
wolfSSL 11:cee25a834751 1078 {
wolfSSL 11:cee25a834751 1079 ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng);
wolfSSL 11:cee25a834751 1080 }
wolfSSL 11:cee25a834751 1081
wolfSSL 11:cee25a834751 1082 /* handle error */
wolfSSL 11:cee25a834751 1083 if (ret < 0 && ret != WC_PENDING_E) {
wolfSSL 11:cee25a834751 1084 if (ret == MP_EXPTMOD_E) {
wolfSSL 11:cee25a834751 1085 /* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */
wolfSSL 11:cee25a834751 1086 WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem");
wolfSSL 11:cee25a834751 1087 }
wolfSSL 11:cee25a834751 1088
wolfSSL 11:cee25a834751 1089 key->state = RSA_STATE_NONE;
wolfSSL 11:cee25a834751 1090 wc_RsaCleanup(key);
wolfSSL 11:cee25a834751 1091 }
wolfSSL 11:cee25a834751 1092
wolfSSL 11:cee25a834751 1093 return ret;
wolfSSL 11:cee25a834751 1094 }
wolfSSL 11:cee25a834751 1095
wolfSSL 11:cee25a834751 1096
wolfSSL 11:cee25a834751 1097 /* Internal Wrappers */
wolfSSL 11:cee25a834751 1098 /* Gives the option of choosing padding type
wolfSSL 11:cee25a834751 1099 in : input to be encrypted
wolfSSL 11:cee25a834751 1100 inLen: length of input buffer
wolfSSL 11:cee25a834751 1101 out: encrypted output
wolfSSL 11:cee25a834751 1102 outLen: length of encrypted output buffer
wolfSSL 11:cee25a834751 1103 key : wolfSSL initialized RSA key struct
wolfSSL 11:cee25a834751 1104 rng : wolfSSL initialized random number struct
wolfSSL 11:cee25a834751 1105 rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
wolfSSL 11:cee25a834751 1106 RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
wolfSSL 11:cee25a834751 1107 pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
wolfSSL 11:cee25a834751 1108 pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD
wolfSSL 11:cee25a834751 1109 hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
wolfSSL 11:cee25a834751 1110 mgf : type of mask generation function to use
wolfSSL 11:cee25a834751 1111 label : optional label
wolfSSL 11:cee25a834751 1112 labelSz : size of optional label buffer */
wolfSSL 11:cee25a834751 1113 static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 1114 word32 outLen, RsaKey* key, int rsa_type,
wolfSSL 11:cee25a834751 1115 byte pad_value, int pad_type,
wolfSSL 11:cee25a834751 1116 enum wc_HashType hash, int mgf,
wolfSSL 11:cee25a834751 1117 byte* label, word32 labelSz, WC_RNG* rng)
wolfSSL 11:cee25a834751 1118 {
wolfSSL 11:cee25a834751 1119 int ret, sz;
wolfSSL 11:cee25a834751 1120
wolfSSL 11:cee25a834751 1121 if (in == NULL || inLen == 0 || out == NULL || key == NULL) {
wolfSSL 11:cee25a834751 1122 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1123 }
wolfSSL 11:cee25a834751 1124
wolfSSL 11:cee25a834751 1125 sz = wc_RsaEncryptSize(key);
wolfSSL 11:cee25a834751 1126 if (sz > (int)outLen) {
wolfSSL 11:cee25a834751 1127 return RSA_BUFFER_E;
wolfSSL 11:cee25a834751 1128 }
wolfSSL 11:cee25a834751 1129
wolfSSL 11:cee25a834751 1130 if (sz < RSA_MIN_PAD_SZ) {
wolfSSL 11:cee25a834751 1131 return WC_KEY_SIZE_E;
wolfSSL 11:cee25a834751 1132 }
wolfSSL 11:cee25a834751 1133
wolfSSL 11:cee25a834751 1134 if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) {
wolfSSL 11:cee25a834751 1135 return RSA_BUFFER_E;
wolfSSL 11:cee25a834751 1136 }
wolfSSL 11:cee25a834751 1137
wolfSSL 11:cee25a834751 1138 switch (key->state) {
wolfSSL 11:cee25a834751 1139 case RSA_STATE_NONE:
wolfSSL 11:cee25a834751 1140 case RSA_STATE_ENCRYPT_PAD:
wolfSSL 11:cee25a834751 1141 key->state = RSA_STATE_ENCRYPT_PAD;
wolfSSL 11:cee25a834751 1142
wolfSSL 11:cee25a834751 1143 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
wolfSSL 11:cee25a834751 1144 defined(HAVE_CAVIUM)
wolfSSL 11:cee25a834751 1145 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && key->n.raw.buf) {
wolfSSL 11:cee25a834751 1146 /* Async operations that include padding */
wolfSSL 11:cee25a834751 1147 if (rsa_type == RSA_PUBLIC_ENCRYPT &&
wolfSSL 11:cee25a834751 1148 pad_value == RSA_BLOCK_TYPE_2) {
wolfSSL 11:cee25a834751 1149 key->state = RSA_STATE_ENCRYPT_RES;
wolfSSL 11:cee25a834751 1150 key->dataLen = key->n.raw.len;
wolfSSL 11:cee25a834751 1151 return NitroxRsaPublicEncrypt(in, inLen, out, outLen, key);
wolfSSL 11:cee25a834751 1152 }
wolfSSL 11:cee25a834751 1153 else if (rsa_type == RSA_PRIVATE_ENCRYPT &&
wolfSSL 11:cee25a834751 1154 pad_value == RSA_BLOCK_TYPE_1) {
wolfSSL 11:cee25a834751 1155 key->state = RSA_STATE_ENCRYPT_RES;
wolfSSL 11:cee25a834751 1156 key->dataLen = key->n.raw.len;
wolfSSL 11:cee25a834751 1157 return NitroxRsaSSL_Sign(in, inLen, out, outLen, key);
wolfSSL 11:cee25a834751 1158 }
wolfSSL 11:cee25a834751 1159 }
wolfSSL 11:cee25a834751 1160 #endif
wolfSSL 11:cee25a834751 1161
wolfSSL 11:cee25a834751 1162 ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash,
wolfSSL 11:cee25a834751 1163 mgf, label, labelSz, key->heap);
wolfSSL 11:cee25a834751 1164 if (ret < 0) {
wolfSSL 11:cee25a834751 1165 break;
wolfSSL 11:cee25a834751 1166 }
wolfSSL 11:cee25a834751 1167
wolfSSL 11:cee25a834751 1168 key->state = RSA_STATE_ENCRYPT_EXPTMOD;
wolfSSL 11:cee25a834751 1169 /* fall through */
wolfSSL 11:cee25a834751 1170
wolfSSL 11:cee25a834751 1171 case RSA_STATE_ENCRYPT_EXPTMOD:
wolfSSL 11:cee25a834751 1172
wolfSSL 11:cee25a834751 1173 key->dataLen = outLen;
wolfSSL 11:cee25a834751 1174 ret = wc_RsaFunction(out, sz, out, &key->dataLen, rsa_type, key, rng);
wolfSSL 11:cee25a834751 1175
wolfSSL 11:cee25a834751 1176 if (ret >= 0 || ret == WC_PENDING_E) {
wolfSSL 11:cee25a834751 1177 key->state = RSA_STATE_ENCRYPT_RES;
wolfSSL 11:cee25a834751 1178 }
wolfSSL 11:cee25a834751 1179 if (ret < 0) {
wolfSSL 11:cee25a834751 1180 break;
wolfSSL 11:cee25a834751 1181 }
wolfSSL 11:cee25a834751 1182
wolfSSL 11:cee25a834751 1183 /* fall through */
wolfSSL 11:cee25a834751 1184
wolfSSL 11:cee25a834751 1185 case RSA_STATE_ENCRYPT_RES:
wolfSSL 11:cee25a834751 1186 ret = key->dataLen;
wolfSSL 11:cee25a834751 1187 break;
wolfSSL 11:cee25a834751 1188
wolfSSL 11:cee25a834751 1189 default:
wolfSSL 11:cee25a834751 1190 ret = BAD_STATE_E;
wolfSSL 11:cee25a834751 1191 break;
wolfSSL 11:cee25a834751 1192 }
wolfSSL 11:cee25a834751 1193
wolfSSL 11:cee25a834751 1194 /* if async pending then return and skip done cleanup below */
wolfSSL 11:cee25a834751 1195 if (ret == WC_PENDING_E) {
wolfSSL 11:cee25a834751 1196 return ret;
wolfSSL 11:cee25a834751 1197 }
wolfSSL 11:cee25a834751 1198
wolfSSL 11:cee25a834751 1199 key->state = RSA_STATE_NONE;
wolfSSL 11:cee25a834751 1200 wc_RsaCleanup(key);
wolfSSL 11:cee25a834751 1201
wolfSSL 11:cee25a834751 1202 return ret;
wolfSSL 11:cee25a834751 1203 }
wolfSSL 11:cee25a834751 1204
wolfSSL 11:cee25a834751 1205 /* Gives the option of choosing padding type
wolfSSL 11:cee25a834751 1206 in : input to be decrypted
wolfSSL 11:cee25a834751 1207 inLen: length of input buffer
wolfSSL 11:cee25a834751 1208 out: decrypted message
wolfSSL 11:cee25a834751 1209 outLen: length of decrypted message in bytes
wolfSSL 11:cee25a834751 1210 outPtr: optional inline output pointer (if provided doing inline)
wolfSSL 11:cee25a834751 1211 key : wolfSSL initialized RSA key struct
wolfSSL 11:cee25a834751 1212 rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT,
wolfSSL 11:cee25a834751 1213 RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT
wolfSSL 11:cee25a834751 1214 pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2
wolfSSL 11:cee25a834751 1215 pad_type : type of padding: WC_RSA_PKCSV15_PAD or WC_RSA_OAEP_PAD
wolfSSL 11:cee25a834751 1216 hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h
wolfSSL 11:cee25a834751 1217 mgf : type of mask generation function to use
wolfSSL 11:cee25a834751 1218 label : optional label
wolfSSL 11:cee25a834751 1219 labelSz : size of optional label buffer */
wolfSSL 11:cee25a834751 1220 static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 1221 word32 outLen, byte** outPtr, RsaKey* key,
wolfSSL 11:cee25a834751 1222 int rsa_type, byte pad_value, int pad_type,
wolfSSL 11:cee25a834751 1223 enum wc_HashType hash, int mgf,
wolfSSL 11:cee25a834751 1224 byte* label, word32 labelSz, WC_RNG* rng)
wolfSSL 11:cee25a834751 1225 {
wolfSSL 11:cee25a834751 1226 int ret = RSA_WRONG_TYPE_E;
wolfSSL 11:cee25a834751 1227
wolfSSL 11:cee25a834751 1228 if (in == NULL || inLen == 0 || out == NULL || key == NULL) {
wolfSSL 11:cee25a834751 1229 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1230 }
wolfSSL 11:cee25a834751 1231
wolfSSL 11:cee25a834751 1232 switch (key->state) {
wolfSSL 11:cee25a834751 1233 case RSA_STATE_NONE:
wolfSSL 11:cee25a834751 1234 case RSA_STATE_DECRYPT_EXPTMOD:
wolfSSL 11:cee25a834751 1235 key->state = RSA_STATE_DECRYPT_EXPTMOD;
wolfSSL 11:cee25a834751 1236 key->dataLen = inLen;
wolfSSL 11:cee25a834751 1237
wolfSSL 11:cee25a834751 1238 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
wolfSSL 11:cee25a834751 1239 defined(HAVE_CAVIUM)
wolfSSL 11:cee25a834751 1240 /* Async operations that include padding */
wolfSSL 11:cee25a834751 1241 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
wolfSSL 11:cee25a834751 1242 if (rsa_type == RSA_PRIVATE_DECRYPT &&
wolfSSL 11:cee25a834751 1243 pad_value == RSA_BLOCK_TYPE_2) {
wolfSSL 11:cee25a834751 1244 key->state = RSA_STATE_DECRYPT_RES;
wolfSSL 11:cee25a834751 1245 key->data = NULL;
wolfSSL 11:cee25a834751 1246 if (outPtr)
wolfSSL 11:cee25a834751 1247 *outPtr = in;
wolfSSL 11:cee25a834751 1248 return NitroxRsaPrivateDecrypt(in, inLen, out, &key->dataLen, key);
wolfSSL 11:cee25a834751 1249 }
wolfSSL 11:cee25a834751 1250 else if (rsa_type == RSA_PUBLIC_DECRYPT &&
wolfSSL 11:cee25a834751 1251 pad_value == RSA_BLOCK_TYPE_1) {
wolfSSL 11:cee25a834751 1252 key->state = RSA_STATE_DECRYPT_RES;
wolfSSL 11:cee25a834751 1253 key->data = NULL;
wolfSSL 11:cee25a834751 1254 return NitroxRsaSSL_Verify(in, inLen, out, &key->dataLen, key);
wolfSSL 11:cee25a834751 1255 }
wolfSSL 11:cee25a834751 1256 }
wolfSSL 11:cee25a834751 1257 #endif
wolfSSL 11:cee25a834751 1258
wolfSSL 11:cee25a834751 1259 /* verify the tmp ptr is NULL, otherwise indicates bad state */
wolfSSL 11:cee25a834751 1260 if (key->data != NULL) {
wolfSSL 11:cee25a834751 1261 ret = BAD_STATE_E;
wolfSSL 11:cee25a834751 1262 break;
wolfSSL 11:cee25a834751 1263 }
wolfSSL 11:cee25a834751 1264
wolfSSL 11:cee25a834751 1265 /* if not doing this inline then allocate a buffer for it */
wolfSSL 11:cee25a834751 1266 if (outPtr == NULL) {
wolfSSL 11:cee25a834751 1267 key->data = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);
wolfSSL 11:cee25a834751 1268 key->dataIsAlloc = 1;
wolfSSL 11:cee25a834751 1269 if (key->data == NULL) {
wolfSSL 11:cee25a834751 1270 ret = MEMORY_E;
wolfSSL 11:cee25a834751 1271 break;
wolfSSL 11:cee25a834751 1272 }
wolfSSL 11:cee25a834751 1273 XMEMCPY(key->data, in, inLen);
wolfSSL 11:cee25a834751 1274 }
wolfSSL 11:cee25a834751 1275 else {
wolfSSL 11:cee25a834751 1276 key->data = out;
wolfSSL 11:cee25a834751 1277 }
wolfSSL 11:cee25a834751 1278 ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen, rsa_type,
wolfSSL 11:cee25a834751 1279 key, rng);
wolfSSL 11:cee25a834751 1280
wolfSSL 11:cee25a834751 1281 if (ret >= 0 || ret == WC_PENDING_E) {
wolfSSL 11:cee25a834751 1282 key->state = RSA_STATE_DECRYPT_UNPAD;
wolfSSL 11:cee25a834751 1283 }
wolfSSL 11:cee25a834751 1284 if (ret < 0) {
wolfSSL 11:cee25a834751 1285 break;
wolfSSL 11:cee25a834751 1286 }
wolfSSL 11:cee25a834751 1287
wolfSSL 11:cee25a834751 1288 /* fall through */
wolfSSL 11:cee25a834751 1289
wolfSSL 11:cee25a834751 1290 case RSA_STATE_DECRYPT_UNPAD:
wolfSSL 11:cee25a834751 1291 {
wolfSSL 11:cee25a834751 1292 byte* pad = NULL;
wolfSSL 11:cee25a834751 1293 ret = wc_RsaUnPad_ex(key->data, key->dataLen, &pad, pad_value, pad_type,
wolfSSL 11:cee25a834751 1294 hash, mgf, label, labelSz, key->heap);
wolfSSL 11:cee25a834751 1295 if (ret > 0 && ret <= (int)outLen && pad != NULL) {
wolfSSL 11:cee25a834751 1296 /* only copy output if not inline */
wolfSSL 11:cee25a834751 1297 if (outPtr == NULL) {
wolfSSL 11:cee25a834751 1298 XMEMCPY(out, pad, ret);
wolfSSL 11:cee25a834751 1299 }
wolfSSL 11:cee25a834751 1300 else {
wolfSSL 11:cee25a834751 1301 *outPtr = pad;
wolfSSL 11:cee25a834751 1302 }
wolfSSL 11:cee25a834751 1303 }
wolfSSL 11:cee25a834751 1304 else if (ret >= 0) {
wolfSSL 11:cee25a834751 1305 ret = RSA_BUFFER_E;
wolfSSL 11:cee25a834751 1306 }
wolfSSL 11:cee25a834751 1307 if (ret < 0) {
wolfSSL 11:cee25a834751 1308 break;
wolfSSL 11:cee25a834751 1309 }
wolfSSL 11:cee25a834751 1310
wolfSSL 11:cee25a834751 1311 key->state = RSA_STATE_DECRYPT_RES;
wolfSSL 11:cee25a834751 1312 /* fall through */
wolfSSL 11:cee25a834751 1313 }
wolfSSL 11:cee25a834751 1314 case RSA_STATE_DECRYPT_RES:
wolfSSL 11:cee25a834751 1315 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \
wolfSSL 11:cee25a834751 1316 defined(HAVE_CAVIUM)
wolfSSL 11:cee25a834751 1317 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
wolfSSL 11:cee25a834751 1318 /* return event ret */
wolfSSL 11:cee25a834751 1319 ret = key->asyncDev.event.ret;
wolfSSL 11:cee25a834751 1320 if (ret == 0) {
wolfSSL 11:cee25a834751 1321 /* convert result */
wolfSSL 11:cee25a834751 1322 byte* dataLen = (byte*)&key->dataLen;
wolfSSL 11:cee25a834751 1323 ret = (dataLen[0] << 8) | (dataLen[1]);
wolfSSL 11:cee25a834751 1324 }
wolfSSL 11:cee25a834751 1325 }
wolfSSL 11:cee25a834751 1326 #endif
wolfSSL 11:cee25a834751 1327 break;
wolfSSL 11:cee25a834751 1328
wolfSSL 11:cee25a834751 1329 default:
wolfSSL 11:cee25a834751 1330 ret = BAD_STATE_E;
wolfSSL 11:cee25a834751 1331 break;
wolfSSL 11:cee25a834751 1332 }
wolfSSL 11:cee25a834751 1333
wolfSSL 11:cee25a834751 1334 /* if async pending then return and skip done cleanup below */
wolfSSL 11:cee25a834751 1335 if (ret == WC_PENDING_E) {
wolfSSL 11:cee25a834751 1336 return ret;
wolfSSL 11:cee25a834751 1337 }
wolfSSL 11:cee25a834751 1338
wolfSSL 11:cee25a834751 1339 key->state = RSA_STATE_NONE;
wolfSSL 11:cee25a834751 1340 wc_RsaCleanup(key);
wolfSSL 11:cee25a834751 1341
wolfSSL 11:cee25a834751 1342 return ret;
wolfSSL 11:cee25a834751 1343 }
wolfSSL 11:cee25a834751 1344
wolfSSL 11:cee25a834751 1345
wolfSSL 11:cee25a834751 1346 /* Public RSA Functions */
wolfSSL 11:cee25a834751 1347 int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen,
wolfSSL 11:cee25a834751 1348 RsaKey* key, WC_RNG* rng)
wolfSSL 11:cee25a834751 1349 {
wolfSSL 11:cee25a834751 1350 return RsaPublicEncryptEx(in, inLen, out, outLen, key,
wolfSSL 11:cee25a834751 1351 RSA_PUBLIC_ENCRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
wolfSSL 11:cee25a834751 1352 WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
wolfSSL 11:cee25a834751 1353 }
wolfSSL 11:cee25a834751 1354
wolfSSL 11:cee25a834751 1355
wolfSSL 11:cee25a834751 1356 #ifndef WC_NO_RSA_OAEP
wolfSSL 11:cee25a834751 1357 int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 1358 word32 outLen, RsaKey* key, WC_RNG* rng, int type,
wolfSSL 11:cee25a834751 1359 enum wc_HashType hash, int mgf, byte* label,
wolfSSL 11:cee25a834751 1360 word32 labelSz)
wolfSSL 11:cee25a834751 1361 {
wolfSSL 11:cee25a834751 1362 return RsaPublicEncryptEx(in, inLen, out, outLen, key, RSA_PUBLIC_ENCRYPT,
wolfSSL 11:cee25a834751 1363 RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, rng);
wolfSSL 11:cee25a834751 1364 }
wolfSSL 11:cee25a834751 1365 #endif /* WC_NO_RSA_OAEP */
wolfSSL 11:cee25a834751 1366
wolfSSL 11:cee25a834751 1367
wolfSSL 11:cee25a834751 1368 int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key)
wolfSSL 11:cee25a834751 1369 {
wolfSSL 11:cee25a834751 1370 WC_RNG* rng = NULL;
wolfSSL 11:cee25a834751 1371 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 1372 rng = key->rng;
wolfSSL 11:cee25a834751 1373 #endif
wolfSSL 11:cee25a834751 1374 return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
wolfSSL 11:cee25a834751 1375 RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
wolfSSL 11:cee25a834751 1376 WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
wolfSSL 11:cee25a834751 1377 }
wolfSSL 11:cee25a834751 1378
wolfSSL 11:cee25a834751 1379
wolfSSL 11:cee25a834751 1380 #ifndef WC_NO_RSA_OAEP
wolfSSL 11:cee25a834751 1381 int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out,
wolfSSL 11:cee25a834751 1382 RsaKey* key, int type, enum wc_HashType hash,
wolfSSL 11:cee25a834751 1383 int mgf, byte* label, word32 labelSz)
wolfSSL 11:cee25a834751 1384 {
wolfSSL 11:cee25a834751 1385 WC_RNG* rng = NULL;
wolfSSL 11:cee25a834751 1386 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 1387 rng = key->rng;
wolfSSL 11:cee25a834751 1388 #endif
wolfSSL 11:cee25a834751 1389 return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
wolfSSL 11:cee25a834751 1390 RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash,
wolfSSL 11:cee25a834751 1391 mgf, label, labelSz, rng);
wolfSSL 11:cee25a834751 1392 }
wolfSSL 11:cee25a834751 1393 #endif /* WC_NO_RSA_OAEP */
wolfSSL 11:cee25a834751 1394
wolfSSL 11:cee25a834751 1395
wolfSSL 11:cee25a834751 1396 int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 1397 word32 outLen, RsaKey* key)
wolfSSL 11:cee25a834751 1398 {
wolfSSL 11:cee25a834751 1399 WC_RNG* rng = NULL;
wolfSSL 11:cee25a834751 1400 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 1401 rng = key->rng;
wolfSSL 11:cee25a834751 1402 #endif
wolfSSL 11:cee25a834751 1403 return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
wolfSSL 11:cee25a834751 1404 RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD,
wolfSSL 11:cee25a834751 1405 WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
wolfSSL 11:cee25a834751 1406 }
wolfSSL 11:cee25a834751 1407
wolfSSL 11:cee25a834751 1408
wolfSSL 11:cee25a834751 1409 #ifndef WC_NO_RSA_OAEP
wolfSSL 11:cee25a834751 1410 int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out,
wolfSSL 11:cee25a834751 1411 word32 outLen, RsaKey* key, int type,
wolfSSL 11:cee25a834751 1412 enum wc_HashType hash, int mgf, byte* label,
wolfSSL 11:cee25a834751 1413 word32 labelSz)
wolfSSL 11:cee25a834751 1414 {
wolfSSL 11:cee25a834751 1415 WC_RNG* rng = NULL;
wolfSSL 11:cee25a834751 1416 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 1417 rng = key->rng;
wolfSSL 11:cee25a834751 1418 #endif
wolfSSL 11:cee25a834751 1419 return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
wolfSSL 11:cee25a834751 1420 RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label,
wolfSSL 11:cee25a834751 1421 labelSz, rng);
wolfSSL 11:cee25a834751 1422 }
wolfSSL 11:cee25a834751 1423 #endif /* WC_NO_RSA_OAEP */
wolfSSL 11:cee25a834751 1424
wolfSSL 11:cee25a834751 1425
wolfSSL 11:cee25a834751 1426 int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key)
wolfSSL 11:cee25a834751 1427 {
wolfSSL 11:cee25a834751 1428 WC_RNG* rng = NULL;
wolfSSL 11:cee25a834751 1429 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 1430 rng = key->rng;
wolfSSL 11:cee25a834751 1431 #endif
wolfSSL 11:cee25a834751 1432 return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key,
wolfSSL 11:cee25a834751 1433 RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
wolfSSL 11:cee25a834751 1434 WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
wolfSSL 11:cee25a834751 1435 }
wolfSSL 11:cee25a834751 1436
wolfSSL 11:cee25a834751 1437 int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen,
wolfSSL 11:cee25a834751 1438 RsaKey* key)
wolfSSL 11:cee25a834751 1439 {
wolfSSL 11:cee25a834751 1440 WC_RNG* rng = NULL;
wolfSSL 11:cee25a834751 1441 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 1442 rng = key->rng;
wolfSSL 11:cee25a834751 1443 #endif
wolfSSL 11:cee25a834751 1444 return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key,
wolfSSL 11:cee25a834751 1445 RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
wolfSSL 11:cee25a834751 1446 WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
wolfSSL 11:cee25a834751 1447 }
wolfSSL 11:cee25a834751 1448
wolfSSL 11:cee25a834751 1449
wolfSSL 11:cee25a834751 1450 int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen,
wolfSSL 11:cee25a834751 1451 RsaKey* key, WC_RNG* rng)
wolfSSL 11:cee25a834751 1452 {
wolfSSL 11:cee25a834751 1453 return RsaPublicEncryptEx(in, inLen, out, outLen, key,
wolfSSL 11:cee25a834751 1454 RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD,
wolfSSL 11:cee25a834751 1455 WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, rng);
wolfSSL 11:cee25a834751 1456 }
wolfSSL 11:cee25a834751 1457
wolfSSL 11:cee25a834751 1458
wolfSSL 11:cee25a834751 1459 int wc_RsaEncryptSize(RsaKey* key)
wolfSSL 11:cee25a834751 1460 {
wolfSSL 11:cee25a834751 1461 return mp_unsigned_bin_size(&key->n);
wolfSSL 11:cee25a834751 1462 }
wolfSSL 11:cee25a834751 1463
wolfSSL 11:cee25a834751 1464
wolfSSL 11:cee25a834751 1465 /* flatten RsaKey structure into individual elements (e, n) */
wolfSSL 11:cee25a834751 1466 int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n,
wolfSSL 11:cee25a834751 1467 word32* nSz)
wolfSSL 11:cee25a834751 1468 {
wolfSSL 11:cee25a834751 1469 int sz, ret;
wolfSSL 11:cee25a834751 1470
wolfSSL 11:cee25a834751 1471 if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL) {
wolfSSL 11:cee25a834751 1472 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1473 }
wolfSSL 11:cee25a834751 1474
wolfSSL 11:cee25a834751 1475 sz = mp_unsigned_bin_size(&key->e);
wolfSSL 11:cee25a834751 1476 if ((word32)sz > *eSz)
wolfSSL 11:cee25a834751 1477 return RSA_BUFFER_E;
wolfSSL 11:cee25a834751 1478 ret = mp_to_unsigned_bin(&key->e, e);
wolfSSL 11:cee25a834751 1479 if (ret != MP_OKAY)
wolfSSL 11:cee25a834751 1480 return ret;
wolfSSL 11:cee25a834751 1481 *eSz = (word32)sz;
wolfSSL 11:cee25a834751 1482
wolfSSL 11:cee25a834751 1483 sz = wc_RsaEncryptSize(key);
wolfSSL 11:cee25a834751 1484 if ((word32)sz > *nSz)
wolfSSL 11:cee25a834751 1485 return RSA_BUFFER_E;
wolfSSL 11:cee25a834751 1486 ret = mp_to_unsigned_bin(&key->n, n);
wolfSSL 11:cee25a834751 1487 if (ret != MP_OKAY)
wolfSSL 11:cee25a834751 1488 return ret;
wolfSSL 11:cee25a834751 1489 *nSz = (word32)sz;
wolfSSL 11:cee25a834751 1490
wolfSSL 11:cee25a834751 1491 return 0;
wolfSSL 11:cee25a834751 1492 }
wolfSSL 11:cee25a834751 1493
wolfSSL 11:cee25a834751 1494 #ifdef WOLFSSL_KEY_GEN
wolfSSL 11:cee25a834751 1495 /* Make an RSA key for size bits, with e specified, 65537 is a good e */
wolfSSL 11:cee25a834751 1496 int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng)
wolfSSL 11:cee25a834751 1497 {
wolfSSL 11:cee25a834751 1498 mp_int p, q, tmp1, tmp2, tmp3;
wolfSSL 11:cee25a834751 1499 int err;
wolfSSL 11:cee25a834751 1500
wolfSSL 11:cee25a834751 1501 if (key == NULL || rng == NULL)
wolfSSL 11:cee25a834751 1502 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1503
wolfSSL 11:cee25a834751 1504 if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
wolfSSL 11:cee25a834751 1505 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1506
wolfSSL 11:cee25a834751 1507 if (e < 3 || (e & 1) == 0)
wolfSSL 11:cee25a834751 1508 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1509
wolfSSL 11:cee25a834751 1510 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
wolfSSL 11:cee25a834751 1511 if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) {
wolfSSL 11:cee25a834751 1512 #ifdef HAVE_CAVIUM
wolfSSL 11:cee25a834751 1513 /* TODO: Not implemented */
wolfSSL 11:cee25a834751 1514 #elif defined(HAVE_INTEL_QA)
wolfSSL 11:cee25a834751 1515 /* TODO: Not implemented */
wolfSSL 11:cee25a834751 1516 #else
wolfSSL 11:cee25a834751 1517 WC_ASYNC_TEST* testDev = &key->asyncDev.test;
wolfSSL 11:cee25a834751 1518 if (testDev->type == ASYNC_TEST_NONE) {
wolfSSL 11:cee25a834751 1519 testDev->type = ASYNC_TEST_RSA_MAKE;
wolfSSL 11:cee25a834751 1520 testDev->rsaMake.rng = rng;
wolfSSL 11:cee25a834751 1521 testDev->rsaMake.key = key;
wolfSSL 11:cee25a834751 1522 testDev->rsaMake.size = size;
wolfSSL 11:cee25a834751 1523 testDev->rsaMake.e = e;
wolfSSL 11:cee25a834751 1524 return WC_PENDING_E;
wolfSSL 11:cee25a834751 1525 }
wolfSSL 11:cee25a834751 1526 #endif
wolfSSL 11:cee25a834751 1527 }
wolfSSL 11:cee25a834751 1528 #endif
wolfSSL 11:cee25a834751 1529
wolfSSL 11:cee25a834751 1530 if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
wolfSSL 11:cee25a834751 1531 return err;
wolfSSL 11:cee25a834751 1532
wolfSSL 11:cee25a834751 1533 err = mp_set_int(&tmp3, e);
wolfSSL 11:cee25a834751 1534
wolfSSL 11:cee25a834751 1535 /* make p */
wolfSSL 11:cee25a834751 1536 if (err == MP_OKAY) {
wolfSSL 11:cee25a834751 1537 do {
wolfSSL 11:cee25a834751 1538 err = mp_rand_prime(&p, size/16, rng, key->heap); /* size in bytes/2 */
wolfSSL 11:cee25a834751 1539
wolfSSL 11:cee25a834751 1540 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1541 err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */
wolfSSL 11:cee25a834751 1542
wolfSSL 11:cee25a834751 1543 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1544 err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(p-1, e) */
wolfSSL 11:cee25a834751 1545 } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divides p-1 */
wolfSSL 11:cee25a834751 1546 }
wolfSSL 11:cee25a834751 1547
wolfSSL 11:cee25a834751 1548 /* make q */
wolfSSL 11:cee25a834751 1549 if (err == MP_OKAY) {
wolfSSL 11:cee25a834751 1550 do {
wolfSSL 11:cee25a834751 1551 err = mp_rand_prime(&q, size/16, rng, key->heap); /* size in bytes/2 */
wolfSSL 11:cee25a834751 1552
wolfSSL 11:cee25a834751 1553 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1554 err = mp_sub_d(&q, 1, &tmp1); /* tmp1 = q-1 */
wolfSSL 11:cee25a834751 1555
wolfSSL 11:cee25a834751 1556 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1557 err = mp_gcd(&tmp1, &tmp3, &tmp2); /* tmp2 = gcd(q-1, e) */
wolfSSL 11:cee25a834751 1558 } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0); /* e divides q-1 */
wolfSSL 11:cee25a834751 1559 }
wolfSSL 11:cee25a834751 1560
wolfSSL 11:cee25a834751 1561 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1562 err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);
wolfSSL 11:cee25a834751 1563
wolfSSL 11:cee25a834751 1564 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1565 err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
wolfSSL 11:cee25a834751 1566
wolfSSL 11:cee25a834751 1567 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1568 err = mp_sub_d(&p, 1, &tmp2); /* tmp2 = p-1 */
wolfSSL 11:cee25a834751 1569
wolfSSL 11:cee25a834751 1570 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1571 err = mp_lcm(&tmp1, &tmp2, &tmp1); /* tmp1 = lcm(p-1, q-1),last loop */
wolfSSL 11:cee25a834751 1572
wolfSSL 11:cee25a834751 1573 /* make key */
wolfSSL 11:cee25a834751 1574 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1575 err = mp_set_int(&key->e, (mp_digit)e); /* key->e = e */
wolfSSL 11:cee25a834751 1576
wolfSSL 11:cee25a834751 1577 if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */
wolfSSL 11:cee25a834751 1578 err = mp_invmod(&key->e, &tmp1, &key->d);
wolfSSL 11:cee25a834751 1579
wolfSSL 11:cee25a834751 1580 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1581 err = mp_mul(&p, &q, &key->n); /* key->n = pq */
wolfSSL 11:cee25a834751 1582
wolfSSL 11:cee25a834751 1583 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1584 err = mp_sub_d(&p, 1, &tmp1);
wolfSSL 11:cee25a834751 1585
wolfSSL 11:cee25a834751 1586 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1587 err = mp_sub_d(&q, 1, &tmp2);
wolfSSL 11:cee25a834751 1588
wolfSSL 11:cee25a834751 1589 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1590 err = mp_mod(&key->d, &tmp1, &key->dP);
wolfSSL 11:cee25a834751 1591
wolfSSL 11:cee25a834751 1592 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1593 err = mp_mod(&key->d, &tmp2, &key->dQ);
wolfSSL 11:cee25a834751 1594
wolfSSL 11:cee25a834751 1595 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1596 err = mp_invmod(&q, &p, &key->u);
wolfSSL 11:cee25a834751 1597
wolfSSL 11:cee25a834751 1598 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1599 err = mp_copy(&p, &key->p);
wolfSSL 11:cee25a834751 1600
wolfSSL 11:cee25a834751 1601 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1602 err = mp_copy(&q, &key->q);
wolfSSL 11:cee25a834751 1603
wolfSSL 11:cee25a834751 1604 if (err == MP_OKAY)
wolfSSL 11:cee25a834751 1605 key->type = RSA_PRIVATE;
wolfSSL 11:cee25a834751 1606
wolfSSL 11:cee25a834751 1607 mp_clear(&tmp3);
wolfSSL 11:cee25a834751 1608 mp_clear(&tmp2);
wolfSSL 11:cee25a834751 1609 mp_clear(&tmp1);
wolfSSL 11:cee25a834751 1610 mp_clear(&q);
wolfSSL 11:cee25a834751 1611 mp_clear(&p);
wolfSSL 11:cee25a834751 1612
wolfSSL 11:cee25a834751 1613 if (err != MP_OKAY) {
wolfSSL 11:cee25a834751 1614 wc_FreeRsaKey(key);
wolfSSL 11:cee25a834751 1615 return err;
wolfSSL 11:cee25a834751 1616 }
wolfSSL 11:cee25a834751 1617
wolfSSL 11:cee25a834751 1618 return 0;
wolfSSL 11:cee25a834751 1619 }
wolfSSL 11:cee25a834751 1620 #endif /* WOLFSSL_KEY_GEN */
wolfSSL 11:cee25a834751 1621
wolfSSL 11:cee25a834751 1622
wolfSSL 11:cee25a834751 1623 #ifdef WC_RSA_BLINDING
wolfSSL 11:cee25a834751 1624
wolfSSL 11:cee25a834751 1625 int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng)
wolfSSL 11:cee25a834751 1626 {
wolfSSL 11:cee25a834751 1627 if (key == NULL)
wolfSSL 11:cee25a834751 1628 return BAD_FUNC_ARG;
wolfSSL 11:cee25a834751 1629
wolfSSL 11:cee25a834751 1630 key->rng = rng;
wolfSSL 11:cee25a834751 1631
wolfSSL 11:cee25a834751 1632 return 0;
wolfSSL 11:cee25a834751 1633 }
wolfSSL 11:cee25a834751 1634
wolfSSL 11:cee25a834751 1635 #endif /* WC_RSA_BLINDING */
wolfSSL 11:cee25a834751 1636
wolfSSL 11:cee25a834751 1637
wolfSSL 11:cee25a834751 1638 #undef ERROR_OUT
wolfSSL 11:cee25a834751 1639
wolfSSL 11:cee25a834751 1640 #endif /* HAVE_FIPS */
wolfSSL 11:cee25a834751 1641 #endif /* NO_RSA */
wolfSSL 11:cee25a834751 1642