wolfSSL 3.11.1 for TLS1.3 beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Tue May 30 06:16:19 2017 +0000
Revision:
13:80fb167dafdf
wolfSSL 3.11.1: TLS1.3 Beta

Who changed what in which revision?

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