Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
wolfcrypt/src/rsa.c@16:048e5e270a58, 2019-11-19 (annotated)
- Committer:
- sPymbed
- Date:
- Tue Nov 19 14:32:16 2019 +0000
- Revision:
- 16:048e5e270a58
- Parent:
- 15:117db924cf7c
working ssl
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
wolfSSL | 15:117db924cf7c | 1 | /* rsa.c |
wolfSSL | 15:117db924cf7c | 2 | * |
wolfSSL | 15:117db924cf7c | 3 | * Copyright (C) 2006-2017 wolfSSL Inc. |
wolfSSL | 15:117db924cf7c | 4 | * |
wolfSSL | 15:117db924cf7c | 5 | * This file is part of wolfSSL. |
wolfSSL | 15:117db924cf7c | 6 | * |
wolfSSL | 15:117db924cf7c | 7 | * wolfSSL is free software; you can redistribute it and/or modify |
wolfSSL | 15:117db924cf7c | 8 | * it under the terms of the GNU General Public License as published by |
wolfSSL | 15:117db924cf7c | 9 | * the Free Software Foundation; either version 2 of the License, or |
wolfSSL | 15:117db924cf7c | 10 | * (at your option) any later version. |
wolfSSL | 15:117db924cf7c | 11 | * |
wolfSSL | 15:117db924cf7c | 12 | * wolfSSL is distributed in the hope that it will be useful, |
wolfSSL | 15:117db924cf7c | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
wolfSSL | 15:117db924cf7c | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
wolfSSL | 15:117db924cf7c | 15 | * GNU General Public License for more details. |
wolfSSL | 15:117db924cf7c | 16 | * |
wolfSSL | 15:117db924cf7c | 17 | * You should have received a copy of the GNU General Public License |
wolfSSL | 15:117db924cf7c | 18 | * along with this program; if not, write to the Free Software |
wolfSSL | 15:117db924cf7c | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA |
wolfSSL | 15:117db924cf7c | 20 | */ |
wolfSSL | 15:117db924cf7c | 21 | |
wolfSSL | 15:117db924cf7c | 22 | |
wolfSSL | 15:117db924cf7c | 23 | #ifdef HAVE_CONFIG_H |
wolfSSL | 15:117db924cf7c | 24 | #include <config.h> |
wolfSSL | 15:117db924cf7c | 25 | #endif |
wolfSSL | 15:117db924cf7c | 26 | |
wolfSSL | 15:117db924cf7c | 27 | #include <wolfssl/wolfcrypt/settings.h> |
wolfSSL | 15:117db924cf7c | 28 | #include <wolfssl/wolfcrypt/error-crypt.h> |
wolfSSL | 15:117db924cf7c | 29 | |
wolfSSL | 15:117db924cf7c | 30 | #ifndef NO_RSA |
wolfSSL | 15:117db924cf7c | 31 | |
wolfSSL | 15:117db924cf7c | 32 | #if defined(HAVE_FIPS) && \ |
wolfSSL | 15:117db924cf7c | 33 | defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2) |
wolfSSL | 15:117db924cf7c | 34 | |
wolfSSL | 15:117db924cf7c | 35 | /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */ |
wolfSSL | 15:117db924cf7c | 36 | #define FIPS_NO_WRAPPERS |
wolfSSL | 15:117db924cf7c | 37 | |
wolfSSL | 15:117db924cf7c | 38 | #ifdef USE_WINDOWS_API |
wolfSSL | 15:117db924cf7c | 39 | #pragma code_seg(".fipsA$e") |
wolfSSL | 15:117db924cf7c | 40 | #pragma const_seg(".fipsB$e") |
wolfSSL | 15:117db924cf7c | 41 | #endif |
wolfSSL | 15:117db924cf7c | 42 | #endif |
wolfSSL | 15:117db924cf7c | 43 | |
wolfSSL | 15:117db924cf7c | 44 | #include <wolfssl/wolfcrypt/rsa.h> |
wolfSSL | 15:117db924cf7c | 45 | |
wolfSSL | 15:117db924cf7c | 46 | #ifdef WOLFSSL_HAVE_SP_RSA |
wolfSSL | 15:117db924cf7c | 47 | #include <wolfssl/wolfcrypt/sp.h> |
wolfSSL | 15:117db924cf7c | 48 | #endif |
wolfSSL | 15:117db924cf7c | 49 | |
wolfSSL | 15:117db924cf7c | 50 | /* |
wolfSSL | 15:117db924cf7c | 51 | Possible RSA enable options: |
wolfSSL | 15:117db924cf7c | 52 | * NO_RSA: Overall control of RSA default: on (not defined) |
wolfSSL | 15:117db924cf7c | 53 | * WC_RSA_BLINDING: Uses Blinding w/ Private Ops default: off |
wolfSSL | 15:117db924cf7c | 54 | Note: slower by ~20% |
wolfSSL | 15:117db924cf7c | 55 | * WOLFSSL_KEY_GEN: Allows Private Key Generation default: off |
wolfSSL | 15:117db924cf7c | 56 | * RSA_LOW_MEM: NON CRT Private Operations, less memory default: off |
wolfSSL | 15:117db924cf7c | 57 | * WC_NO_RSA_OAEP: Disables RSA OAEP padding default: on (not defined) |
wolfSSL | 15:117db924cf7c | 58 | |
wolfSSL | 15:117db924cf7c | 59 | */ |
wolfSSL | 15:117db924cf7c | 60 | |
wolfSSL | 15:117db924cf7c | 61 | /* |
wolfSSL | 15:117db924cf7c | 62 | RSA Key Size Configuration: |
wolfSSL | 15:117db924cf7c | 63 | * FP_MAX_BITS: With USE_FAST_MATH only default: 4096 |
wolfSSL | 15:117db924cf7c | 64 | If USE_FAST_MATH then use this to override default. |
wolfSSL | 15:117db924cf7c | 65 | Value is key size * 2. Example: RSA 3072 = 6144 |
wolfSSL | 15:117db924cf7c | 66 | */ |
wolfSSL | 15:117db924cf7c | 67 | |
wolfSSL | 15:117db924cf7c | 68 | |
wolfSSL | 15:117db924cf7c | 69 | /* If building for old FIPS. */ |
wolfSSL | 15:117db924cf7c | 70 | #if defined(HAVE_FIPS) && \ |
wolfSSL | 15:117db924cf7c | 71 | (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) |
wolfSSL | 15:117db924cf7c | 72 | |
wolfSSL | 15:117db924cf7c | 73 | int wc_InitRsaKey(RsaKey* key, void* ptr) |
wolfSSL | 15:117db924cf7c | 74 | { |
wolfSSL | 15:117db924cf7c | 75 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 76 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 77 | } |
wolfSSL | 15:117db924cf7c | 78 | |
wolfSSL | 15:117db924cf7c | 79 | return InitRsaKey_fips(key, ptr); |
wolfSSL | 15:117db924cf7c | 80 | } |
wolfSSL | 15:117db924cf7c | 81 | |
wolfSSL | 15:117db924cf7c | 82 | |
wolfSSL | 15:117db924cf7c | 83 | int wc_InitRsaKey_ex(RsaKey* key, void* ptr, int devId) |
wolfSSL | 15:117db924cf7c | 84 | { |
wolfSSL | 15:117db924cf7c | 85 | (void)devId; |
wolfSSL | 15:117db924cf7c | 86 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 87 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 88 | } |
wolfSSL | 15:117db924cf7c | 89 | return InitRsaKey_fips(key, ptr); |
wolfSSL | 15:117db924cf7c | 90 | } |
wolfSSL | 15:117db924cf7c | 91 | |
wolfSSL | 15:117db924cf7c | 92 | |
wolfSSL | 15:117db924cf7c | 93 | int wc_FreeRsaKey(RsaKey* key) |
wolfSSL | 15:117db924cf7c | 94 | { |
wolfSSL | 15:117db924cf7c | 95 | return FreeRsaKey_fips(key); |
wolfSSL | 15:117db924cf7c | 96 | } |
wolfSSL | 15:117db924cf7c | 97 | |
wolfSSL | 15:117db924cf7c | 98 | |
wolfSSL | 15:117db924cf7c | 99 | int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 100 | word32 outLen, RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 101 | { |
wolfSSL | 15:117db924cf7c | 102 | if (in == NULL || out == NULL || key == NULL || rng == NULL) { |
wolfSSL | 15:117db924cf7c | 103 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 104 | } |
wolfSSL | 15:117db924cf7c | 105 | return RsaPublicEncrypt_fips(in, inLen, out, outLen, key, rng); |
wolfSSL | 15:117db924cf7c | 106 | } |
wolfSSL | 15:117db924cf7c | 107 | |
wolfSSL | 15:117db924cf7c | 108 | |
wolfSSL | 15:117db924cf7c | 109 | int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, |
wolfSSL | 15:117db924cf7c | 110 | RsaKey* key) |
wolfSSL | 15:117db924cf7c | 111 | { |
wolfSSL | 15:117db924cf7c | 112 | if (in == NULL || out == NULL || key == NULL) { |
wolfSSL | 15:117db924cf7c | 113 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 114 | } |
wolfSSL | 15:117db924cf7c | 115 | return RsaPrivateDecryptInline_fips(in, inLen, out, key); |
wolfSSL | 15:117db924cf7c | 116 | } |
wolfSSL | 15:117db924cf7c | 117 | |
wolfSSL | 15:117db924cf7c | 118 | |
wolfSSL | 15:117db924cf7c | 119 | int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 120 | word32 outLen, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 121 | { |
wolfSSL | 15:117db924cf7c | 122 | if (in == NULL || out == NULL || key == NULL) { |
wolfSSL | 15:117db924cf7c | 123 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 124 | } |
wolfSSL | 15:117db924cf7c | 125 | return RsaPrivateDecrypt_fips(in, inLen, out, outLen, key); |
wolfSSL | 15:117db924cf7c | 126 | } |
wolfSSL | 15:117db924cf7c | 127 | |
wolfSSL | 15:117db924cf7c | 128 | |
wolfSSL | 15:117db924cf7c | 129 | int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 130 | word32 outLen, RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 131 | { |
wolfSSL | 15:117db924cf7c | 132 | if (in == NULL || out == NULL || key == NULL || inLen == 0) { |
wolfSSL | 15:117db924cf7c | 133 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 134 | } |
wolfSSL | 15:117db924cf7c | 135 | return RsaSSL_Sign_fips(in, inLen, out, outLen, key, rng); |
wolfSSL | 15:117db924cf7c | 136 | } |
wolfSSL | 15:117db924cf7c | 137 | |
wolfSSL | 15:117db924cf7c | 138 | |
wolfSSL | 15:117db924cf7c | 139 | int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 140 | { |
wolfSSL | 15:117db924cf7c | 141 | if (in == NULL || out == NULL || key == NULL) { |
wolfSSL | 15:117db924cf7c | 142 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 143 | } |
wolfSSL | 15:117db924cf7c | 144 | return RsaSSL_VerifyInline_fips(in, inLen, out, key); |
wolfSSL | 15:117db924cf7c | 145 | } |
wolfSSL | 15:117db924cf7c | 146 | |
wolfSSL | 15:117db924cf7c | 147 | |
wolfSSL | 15:117db924cf7c | 148 | int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 149 | word32 outLen, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 150 | { |
wolfSSL | 15:117db924cf7c | 151 | if (in == NULL || out == NULL || key == NULL || inLen == 0) { |
wolfSSL | 15:117db924cf7c | 152 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 153 | } |
wolfSSL | 15:117db924cf7c | 154 | return RsaSSL_Verify_fips(in, inLen, out, outLen, key); |
wolfSSL | 15:117db924cf7c | 155 | } |
wolfSSL | 15:117db924cf7c | 156 | |
wolfSSL | 15:117db924cf7c | 157 | |
wolfSSL | 15:117db924cf7c | 158 | int wc_RsaEncryptSize(RsaKey* key) |
wolfSSL | 15:117db924cf7c | 159 | { |
wolfSSL | 15:117db924cf7c | 160 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 161 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 162 | } |
wolfSSL | 15:117db924cf7c | 163 | return RsaEncryptSize_fips(key); |
wolfSSL | 15:117db924cf7c | 164 | } |
wolfSSL | 15:117db924cf7c | 165 | |
wolfSSL | 15:117db924cf7c | 166 | |
wolfSSL | 15:117db924cf7c | 167 | int wc_RsaFlattenPublicKey(RsaKey* key, byte* a, word32* aSz, byte* b, |
wolfSSL | 15:117db924cf7c | 168 | word32* bSz) |
wolfSSL | 15:117db924cf7c | 169 | { |
wolfSSL | 15:117db924cf7c | 170 | |
wolfSSL | 15:117db924cf7c | 171 | /* not specified as fips so not needing _fips */ |
wolfSSL | 15:117db924cf7c | 172 | return RsaFlattenPublicKey(key, a, aSz, b, bSz); |
wolfSSL | 15:117db924cf7c | 173 | } |
wolfSSL | 15:117db924cf7c | 174 | |
wolfSSL | 15:117db924cf7c | 175 | |
wolfSSL | 15:117db924cf7c | 176 | #ifdef WOLFSSL_KEY_GEN |
wolfSSL | 15:117db924cf7c | 177 | int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 178 | { |
wolfSSL | 15:117db924cf7c | 179 | return MakeRsaKey(key, size, e, rng); |
wolfSSL | 15:117db924cf7c | 180 | } |
wolfSSL | 15:117db924cf7c | 181 | #endif |
wolfSSL | 15:117db924cf7c | 182 | |
wolfSSL | 15:117db924cf7c | 183 | |
wolfSSL | 15:117db924cf7c | 184 | /* these are functions in asn and are routed to wolfssl/wolfcrypt/asn.c |
wolfSSL | 15:117db924cf7c | 185 | * wc_RsaPrivateKeyDecode |
wolfSSL | 15:117db924cf7c | 186 | * wc_RsaPublicKeyDecode |
wolfSSL | 15:117db924cf7c | 187 | */ |
wolfSSL | 15:117db924cf7c | 188 | |
wolfSSL | 15:117db924cf7c | 189 | #else /* else build without fips, or for new fips */ |
wolfSSL | 15:117db924cf7c | 190 | |
wolfSSL | 15:117db924cf7c | 191 | #include <wolfssl/wolfcrypt/random.h> |
wolfSSL | 15:117db924cf7c | 192 | #include <wolfssl/wolfcrypt/logging.h> |
wolfSSL | 15:117db924cf7c | 193 | #ifdef WOLF_CRYPTO_DEV |
wolfSSL | 15:117db924cf7c | 194 | #include <wolfssl/wolfcrypt/cryptodev.h> |
wolfSSL | 15:117db924cf7c | 195 | #endif |
wolfSSL | 15:117db924cf7c | 196 | #ifdef NO_INLINE |
wolfSSL | 15:117db924cf7c | 197 | #include <wolfssl/wolfcrypt/misc.h> |
wolfSSL | 15:117db924cf7c | 198 | #else |
wolfSSL | 15:117db924cf7c | 199 | #define WOLFSSL_MISC_INCLUDED |
wolfSSL | 15:117db924cf7c | 200 | #include <wolfcrypt/src/misc.c> |
wolfSSL | 15:117db924cf7c | 201 | #endif |
wolfSSL | 15:117db924cf7c | 202 | |
wolfSSL | 15:117db924cf7c | 203 | #define ERROR_OUT(x) { ret = (x); goto done;} |
wolfSSL | 15:117db924cf7c | 204 | |
wolfSSL | 15:117db924cf7c | 205 | |
wolfSSL | 15:117db924cf7c | 206 | enum { |
wolfSSL | 15:117db924cf7c | 207 | RSA_STATE_NONE = 0, |
wolfSSL | 15:117db924cf7c | 208 | |
wolfSSL | 15:117db924cf7c | 209 | RSA_STATE_ENCRYPT_PAD, |
wolfSSL | 15:117db924cf7c | 210 | RSA_STATE_ENCRYPT_EXPTMOD, |
wolfSSL | 15:117db924cf7c | 211 | RSA_STATE_ENCRYPT_RES, |
wolfSSL | 15:117db924cf7c | 212 | |
wolfSSL | 15:117db924cf7c | 213 | RSA_STATE_DECRYPT_EXPTMOD, |
wolfSSL | 15:117db924cf7c | 214 | RSA_STATE_DECRYPT_UNPAD, |
wolfSSL | 15:117db924cf7c | 215 | RSA_STATE_DECRYPT_RES, |
wolfSSL | 15:117db924cf7c | 216 | }; |
wolfSSL | 15:117db924cf7c | 217 | |
wolfSSL | 15:117db924cf7c | 218 | static void wc_RsaCleanup(RsaKey* key) |
wolfSSL | 15:117db924cf7c | 219 | { |
wolfSSL | 15:117db924cf7c | 220 | if (key && key->data) { |
wolfSSL | 15:117db924cf7c | 221 | /* make sure any allocated memory is free'd */ |
wolfSSL | 15:117db924cf7c | 222 | if (key->dataIsAlloc) { |
wolfSSL | 15:117db924cf7c | 223 | if (key->type == RSA_PRIVATE_DECRYPT || |
wolfSSL | 15:117db924cf7c | 224 | key->type == RSA_PRIVATE_ENCRYPT) { |
wolfSSL | 15:117db924cf7c | 225 | ForceZero(key->data, key->dataLen); |
wolfSSL | 15:117db924cf7c | 226 | } |
wolfSSL | 15:117db924cf7c | 227 | XFREE(key->data, key->heap, DYNAMIC_TYPE_WOLF_BIGINT); |
wolfSSL | 15:117db924cf7c | 228 | key->dataIsAlloc = 0; |
wolfSSL | 15:117db924cf7c | 229 | } |
wolfSSL | 15:117db924cf7c | 230 | key->data = NULL; |
wolfSSL | 15:117db924cf7c | 231 | key->dataLen = 0; |
wolfSSL | 15:117db924cf7c | 232 | } |
wolfSSL | 15:117db924cf7c | 233 | } |
wolfSSL | 15:117db924cf7c | 234 | |
wolfSSL | 15:117db924cf7c | 235 | int wc_InitRsaKey_ex(RsaKey* key, void* heap, int devId) |
wolfSSL | 15:117db924cf7c | 236 | { |
wolfSSL | 15:117db924cf7c | 237 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 238 | |
wolfSSL | 15:117db924cf7c | 239 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 240 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 241 | } |
wolfSSL | 15:117db924cf7c | 242 | |
wolfSSL | 15:117db924cf7c | 243 | XMEMSET(key, 0, sizeof(RsaKey)); |
wolfSSL | 15:117db924cf7c | 244 | |
wolfSSL | 15:117db924cf7c | 245 | key->type = RSA_TYPE_UNKNOWN; |
wolfSSL | 15:117db924cf7c | 246 | key->state = RSA_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 247 | key->heap = heap; |
wolfSSL | 15:117db924cf7c | 248 | key->data = NULL; |
wolfSSL | 15:117db924cf7c | 249 | key->dataLen = 0; |
wolfSSL | 15:117db924cf7c | 250 | key->dataIsAlloc = 0; |
wolfSSL | 15:117db924cf7c | 251 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 252 | key->rng = NULL; |
wolfSSL | 15:117db924cf7c | 253 | #endif |
wolfSSL | 15:117db924cf7c | 254 | |
wolfSSL | 15:117db924cf7c | 255 | #ifdef WOLF_CRYPTO_DEV |
wolfSSL | 15:117db924cf7c | 256 | key->devId = devId; |
wolfSSL | 15:117db924cf7c | 257 | #else |
wolfSSL | 15:117db924cf7c | 258 | (void)devId; |
wolfSSL | 15:117db924cf7c | 259 | #endif |
wolfSSL | 15:117db924cf7c | 260 | |
wolfSSL | 15:117db924cf7c | 261 | #ifdef WOLFSSL_ASYNC_CRYPT |
wolfSSL | 15:117db924cf7c | 262 | #ifdef WOLFSSL_CERT_GEN |
wolfSSL | 15:117db924cf7c | 263 | XMEMSET(&key->certSignCtx, 0, sizeof(CertSignCtx)); |
wolfSSL | 15:117db924cf7c | 264 | #endif |
wolfSSL | 15:117db924cf7c | 265 | |
wolfSSL | 15:117db924cf7c | 266 | #ifdef WC_ASYNC_ENABLE_RSA |
wolfSSL | 15:117db924cf7c | 267 | /* handle as async */ |
wolfSSL | 15:117db924cf7c | 268 | ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA, |
wolfSSL | 15:117db924cf7c | 269 | key->heap, devId); |
wolfSSL | 15:117db924cf7c | 270 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 271 | return ret; |
wolfSSL | 15:117db924cf7c | 272 | #endif /* WC_ASYNC_ENABLE_RSA */ |
wolfSSL | 15:117db924cf7c | 273 | #endif /* WOLFSSL_ASYNC_CRYPT */ |
wolfSSL | 15:117db924cf7c | 274 | |
wolfSSL | 15:117db924cf7c | 275 | ret = mp_init_multi(&key->n, &key->e, NULL, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 276 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 277 | return ret; |
wolfSSL | 15:117db924cf7c | 278 | |
wolfSSL | 15:117db924cf7c | 279 | #if !defined(WOLFSSL_KEY_GEN) && !defined(OPENSSL_EXTRA) && defined(RSA_LOW_MEM) |
wolfSSL | 15:117db924cf7c | 280 | ret = mp_init_multi(&key->d, &key->p, &key->q, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 281 | #else |
wolfSSL | 15:117db924cf7c | 282 | ret = mp_init_multi(&key->d, &key->p, &key->q, &key->dP, &key->dQ, &key->u); |
wolfSSL | 15:117db924cf7c | 283 | #endif |
wolfSSL | 15:117db924cf7c | 284 | if (ret != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 285 | mp_clear(&key->n); |
wolfSSL | 15:117db924cf7c | 286 | mp_clear(&key->e); |
wolfSSL | 15:117db924cf7c | 287 | return ret; |
wolfSSL | 15:117db924cf7c | 288 | } |
wolfSSL | 15:117db924cf7c | 289 | |
wolfSSL | 15:117db924cf7c | 290 | #ifdef WOLFSSL_XILINX_CRYPT |
wolfSSL | 15:117db924cf7c | 291 | key->pubExp = 0; |
wolfSSL | 15:117db924cf7c | 292 | key->mod = NULL; |
wolfSSL | 15:117db924cf7c | 293 | #endif |
wolfSSL | 15:117db924cf7c | 294 | |
wolfSSL | 15:117db924cf7c | 295 | return ret; |
wolfSSL | 15:117db924cf7c | 296 | } |
wolfSSL | 15:117db924cf7c | 297 | |
wolfSSL | 15:117db924cf7c | 298 | int wc_InitRsaKey(RsaKey* key, void* heap) |
wolfSSL | 15:117db924cf7c | 299 | { |
wolfSSL | 15:117db924cf7c | 300 | return wc_InitRsaKey_ex(key, heap, INVALID_DEVID); |
wolfSSL | 15:117db924cf7c | 301 | } |
wolfSSL | 15:117db924cf7c | 302 | |
wolfSSL | 15:117db924cf7c | 303 | |
wolfSSL | 15:117db924cf7c | 304 | #ifdef WOLFSSL_XILINX_CRYPT |
wolfSSL | 15:117db924cf7c | 305 | #define MAX_E_SIZE 4 |
wolfSSL | 15:117db924cf7c | 306 | /* Used to setup hardware state |
wolfSSL | 15:117db924cf7c | 307 | * |
wolfSSL | 15:117db924cf7c | 308 | * key the RSA key to setup |
wolfSSL | 15:117db924cf7c | 309 | * |
wolfSSL | 15:117db924cf7c | 310 | * returns 0 on success |
wolfSSL | 15:117db924cf7c | 311 | */ |
wolfSSL | 15:117db924cf7c | 312 | int wc_InitRsaHw(RsaKey* key) |
wolfSSL | 15:117db924cf7c | 313 | { |
wolfSSL | 15:117db924cf7c | 314 | unsigned char* m; /* RSA modulous */ |
wolfSSL | 15:117db924cf7c | 315 | word32 e = 0; /* RSA public exponent */ |
wolfSSL | 15:117db924cf7c | 316 | int mSz; |
wolfSSL | 15:117db924cf7c | 317 | int eSz; |
wolfSSL | 15:117db924cf7c | 318 | |
wolfSSL | 15:117db924cf7c | 319 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 320 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 321 | } |
wolfSSL | 15:117db924cf7c | 322 | |
wolfSSL | 15:117db924cf7c | 323 | mSz = mp_unsigned_bin_size(&(key->n)); |
wolfSSL | 15:117db924cf7c | 324 | m = (unsigned char*)XMALLOC(mSz, key->heap, DYNAMIC_TYPE_KEY); |
wolfSSL | 15:117db924cf7c | 325 | if (m == 0) { |
wolfSSL | 15:117db924cf7c | 326 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 327 | } |
wolfSSL | 15:117db924cf7c | 328 | |
wolfSSL | 15:117db924cf7c | 329 | if (mp_to_unsigned_bin(&(key->n), m) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 330 | WOLFSSL_MSG("Unable to get RSA key modulus"); |
wolfSSL | 15:117db924cf7c | 331 | XFREE(m, key->heap, DYNAMIC_TYPE_KEY); |
wolfSSL | 15:117db924cf7c | 332 | return MP_READ_E; |
wolfSSL | 15:117db924cf7c | 333 | } |
wolfSSL | 15:117db924cf7c | 334 | |
wolfSSL | 15:117db924cf7c | 335 | eSz = mp_unsigned_bin_size(&(key->e)); |
wolfSSL | 15:117db924cf7c | 336 | if (eSz > MAX_E_SIZE) { |
wolfSSL | 15:117db924cf7c | 337 | WOLFSSL_MSG("Exponent of size 4 bytes expected"); |
wolfSSL | 15:117db924cf7c | 338 | XFREE(m, key->heap, DYNAMIC_TYPE_KEY); |
wolfSSL | 15:117db924cf7c | 339 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 340 | } |
wolfSSL | 15:117db924cf7c | 341 | |
wolfSSL | 15:117db924cf7c | 342 | if (mp_to_unsigned_bin(&(key->e), (byte*)&e + (MAX_E_SIZE - eSz)) |
wolfSSL | 15:117db924cf7c | 343 | != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 344 | XFREE(m, key->heap, DYNAMIC_TYPE_KEY); |
wolfSSL | 15:117db924cf7c | 345 | WOLFSSL_MSG("Unable to get RSA key exponent"); |
wolfSSL | 15:117db924cf7c | 346 | return MP_READ_E; |
wolfSSL | 15:117db924cf7c | 347 | } |
wolfSSL | 15:117db924cf7c | 348 | |
wolfSSL | 15:117db924cf7c | 349 | /* check for existing mod buffer to avoid memory leak */ |
wolfSSL | 15:117db924cf7c | 350 | if (key->mod != NULL) { |
wolfSSL | 15:117db924cf7c | 351 | XFREE(key->mod, key->heap, DYNAMIC_TYPE_KEY); |
wolfSSL | 15:117db924cf7c | 352 | } |
wolfSSL | 15:117db924cf7c | 353 | |
wolfSSL | 15:117db924cf7c | 354 | key->pubExp = e; |
wolfSSL | 15:117db924cf7c | 355 | key->mod = m; |
wolfSSL | 15:117db924cf7c | 356 | |
wolfSSL | 15:117db924cf7c | 357 | if (XSecure_RsaInitialize(&(key->xRsa), key->mod, NULL, |
wolfSSL | 15:117db924cf7c | 358 | (byte*)&(key->pubExp)) != XST_SUCCESS) { |
wolfSSL | 15:117db924cf7c | 359 | WOLFSSL_MSG("Unable to initialize RSA on hardware"); |
wolfSSL | 15:117db924cf7c | 360 | XFREE(m, key->heap, DYNAMIC_TYPE_KEY); |
wolfSSL | 15:117db924cf7c | 361 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 362 | } |
wolfSSL | 15:117db924cf7c | 363 | |
wolfSSL | 15:117db924cf7c | 364 | #ifdef WOLFSSL_XILINX_PATCH |
wolfSSL | 15:117db924cf7c | 365 | /* currently a patch of xsecure_rsa.c for 2048 bit keys */ |
wolfSSL | 15:117db924cf7c | 366 | if (wc_RsaEncryptSize(key) == 256) { |
wolfSSL | 15:117db924cf7c | 367 | if (XSecure_RsaSetSize(&(key->xRsa), 2048) != XST_SUCCESS) { |
wolfSSL | 15:117db924cf7c | 368 | WOLFSSL_MSG("Unable to set RSA key size on hardware"); |
wolfSSL | 15:117db924cf7c | 369 | XFREE(m, key->heap, DYNAMIC_TYPE_KEY); |
wolfSSL | 15:117db924cf7c | 370 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 371 | } |
wolfSSL | 15:117db924cf7c | 372 | } |
wolfSSL | 15:117db924cf7c | 373 | #endif |
wolfSSL | 15:117db924cf7c | 374 | |
wolfSSL | 15:117db924cf7c | 375 | return 0; |
wolfSSL | 15:117db924cf7c | 376 | } |
wolfSSL | 15:117db924cf7c | 377 | #endif /* WOLFSSL_XILINX_CRYPT */ |
wolfSSL | 15:117db924cf7c | 378 | |
wolfSSL | 15:117db924cf7c | 379 | int wc_FreeRsaKey(RsaKey* key) |
wolfSSL | 15:117db924cf7c | 380 | { |
wolfSSL | 15:117db924cf7c | 381 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 382 | |
wolfSSL | 15:117db924cf7c | 383 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 384 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 385 | } |
wolfSSL | 15:117db924cf7c | 386 | |
wolfSSL | 15:117db924cf7c | 387 | wc_RsaCleanup(key); |
wolfSSL | 15:117db924cf7c | 388 | |
wolfSSL | 15:117db924cf7c | 389 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) |
wolfSSL | 15:117db924cf7c | 390 | wolfAsync_DevCtxFree(&key->asyncDev, WOLFSSL_ASYNC_MARKER_RSA); |
wolfSSL | 15:117db924cf7c | 391 | #endif |
wolfSSL | 15:117db924cf7c | 392 | |
wolfSSL | 15:117db924cf7c | 393 | if (key->type == RSA_PRIVATE) { |
wolfSSL | 15:117db924cf7c | 394 | #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) |
wolfSSL | 15:117db924cf7c | 395 | mp_forcezero(&key->u); |
wolfSSL | 15:117db924cf7c | 396 | mp_forcezero(&key->dQ); |
wolfSSL | 15:117db924cf7c | 397 | mp_forcezero(&key->dP); |
wolfSSL | 15:117db924cf7c | 398 | #endif |
wolfSSL | 15:117db924cf7c | 399 | mp_forcezero(&key->q); |
wolfSSL | 15:117db924cf7c | 400 | mp_forcezero(&key->p); |
wolfSSL | 15:117db924cf7c | 401 | mp_forcezero(&key->d); |
wolfSSL | 15:117db924cf7c | 402 | } |
wolfSSL | 15:117db924cf7c | 403 | /* private part */ |
wolfSSL | 15:117db924cf7c | 404 | #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) |
wolfSSL | 15:117db924cf7c | 405 | mp_clear(&key->u); |
wolfSSL | 15:117db924cf7c | 406 | mp_clear(&key->dQ); |
wolfSSL | 15:117db924cf7c | 407 | mp_clear(&key->dP); |
wolfSSL | 15:117db924cf7c | 408 | #endif |
wolfSSL | 15:117db924cf7c | 409 | mp_clear(&key->q); |
wolfSSL | 15:117db924cf7c | 410 | mp_clear(&key->p); |
wolfSSL | 15:117db924cf7c | 411 | mp_clear(&key->d); |
wolfSSL | 15:117db924cf7c | 412 | |
wolfSSL | 15:117db924cf7c | 413 | /* public part */ |
wolfSSL | 15:117db924cf7c | 414 | mp_clear(&key->e); |
wolfSSL | 15:117db924cf7c | 415 | mp_clear(&key->n); |
wolfSSL | 15:117db924cf7c | 416 | |
wolfSSL | 15:117db924cf7c | 417 | #ifdef WOLFSSL_XILINX_CRYPT |
wolfSSL | 15:117db924cf7c | 418 | XFREE(key->mod, key->heap, DYNAMIC_TYPE_KEY); |
wolfSSL | 15:117db924cf7c | 419 | key->mod = NULL; |
wolfSSL | 15:117db924cf7c | 420 | #endif |
wolfSSL | 15:117db924cf7c | 421 | |
wolfSSL | 15:117db924cf7c | 422 | return ret; |
wolfSSL | 15:117db924cf7c | 423 | } |
wolfSSL | 15:117db924cf7c | 424 | |
wolfSSL | 15:117db924cf7c | 425 | |
wolfSSL | 15:117db924cf7c | 426 | /* Check the pair-wise consistency of the RSA key. |
wolfSSL | 15:117db924cf7c | 427 | * From NIST SP 800-56B, section 6.4.1.1. |
wolfSSL | 15:117db924cf7c | 428 | * Verify that k = (k^e)^d, for some k: 1 < k < n-1. */ |
wolfSSL | 15:117db924cf7c | 429 | int wc_CheckRsaKey(RsaKey* key) |
wolfSSL | 15:117db924cf7c | 430 | { |
wolfSSL | 15:117db924cf7c | 431 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 432 | mp_int *k = NULL, *tmp = NULL; |
wolfSSL | 15:117db924cf7c | 433 | #else |
wolfSSL | 15:117db924cf7c | 434 | mp_int k[1], tmp[1]; |
wolfSSL | 15:117db924cf7c | 435 | #endif |
wolfSSL | 15:117db924cf7c | 436 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 437 | |
wolfSSL | 15:117db924cf7c | 438 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 439 | k = (mp_int*)XMALLOC(sizeof(mp_int) * 2, NULL, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 440 | if (k == NULL) |
wolfSSL | 15:117db924cf7c | 441 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 442 | tmp = k + 1; |
wolfSSL | 15:117db924cf7c | 443 | #endif |
wolfSSL | 15:117db924cf7c | 444 | |
wolfSSL | 15:117db924cf7c | 445 | if (mp_init_multi(k, tmp, NULL, NULL, NULL, NULL) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 446 | ret = MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 447 | |
wolfSSL | 15:117db924cf7c | 448 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 449 | if (key == NULL) |
wolfSSL | 15:117db924cf7c | 450 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 451 | } |
wolfSSL | 15:117db924cf7c | 452 | |
wolfSSL | 15:117db924cf7c | 453 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 454 | if (mp_set_int(k, 0x2342) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 455 | ret = MP_READ_E; |
wolfSSL | 15:117db924cf7c | 456 | } |
wolfSSL | 15:117db924cf7c | 457 | |
wolfSSL | 15:117db924cf7c | 458 | #ifdef WOLFSSL_SP_RSA |
wolfSSL | 15:117db924cf7c | 459 | #ifndef WOLFSSL_SP_NO_2048 |
wolfSSL | 15:117db924cf7c | 460 | if (mp_count_bits(&key->n) == 2048) { |
wolfSSL | 15:117db924cf7c | 461 | ret = sp_ModExp_2048(k, &key->e, &key->n, tmp); |
wolfSSL | 15:117db924cf7c | 462 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 463 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 464 | ret = sp_ModExp_2048(tmp, &key->d, &key->n, tmp); |
wolfSSL | 15:117db924cf7c | 465 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 466 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 467 | } |
wolfSSL | 15:117db924cf7c | 468 | else |
wolfSSL | 15:117db924cf7c | 469 | #endif |
wolfSSL | 15:117db924cf7c | 470 | #ifndef WOLFSSL_SP_NO_3072 |
wolfSSL | 15:117db924cf7c | 471 | if (mp_count_bits(&key->n) == 3072) { |
wolfSSL | 15:117db924cf7c | 472 | ret = sp_ModExp_3072(k, &key->e, &key->n, tmp); |
wolfSSL | 15:117db924cf7c | 473 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 474 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 475 | ret = sp_ModExp_3072(tmp, &key->d, &key->n, tmp); |
wolfSSL | 15:117db924cf7c | 476 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 477 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 478 | } |
wolfSSL | 15:117db924cf7c | 479 | else |
wolfSSL | 15:117db924cf7c | 480 | #endif |
wolfSSL | 15:117db924cf7c | 481 | #endif |
wolfSSL | 15:117db924cf7c | 482 | #ifdef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 483 | { |
wolfSSL | 15:117db924cf7c | 484 | ret = WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 485 | } |
wolfSSL | 15:117db924cf7c | 486 | #else |
wolfSSL | 15:117db924cf7c | 487 | { |
wolfSSL | 15:117db924cf7c | 488 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 489 | if (mp_exptmod(k, &key->e, &key->n, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 490 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 491 | } |
wolfSSL | 15:117db924cf7c | 492 | |
wolfSSL | 15:117db924cf7c | 493 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 494 | if (mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 495 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 496 | } |
wolfSSL | 15:117db924cf7c | 497 | } |
wolfSSL | 15:117db924cf7c | 498 | #endif |
wolfSSL | 15:117db924cf7c | 499 | |
wolfSSL | 15:117db924cf7c | 500 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 501 | if (mp_cmp(k, tmp) != MP_EQ) |
wolfSSL | 15:117db924cf7c | 502 | ret = RSA_KEY_PAIR_E; |
wolfSSL | 15:117db924cf7c | 503 | } |
wolfSSL | 15:117db924cf7c | 504 | |
wolfSSL | 15:117db924cf7c | 505 | mp_forcezero(tmp); |
wolfSSL | 15:117db924cf7c | 506 | mp_clear(tmp); |
wolfSSL | 15:117db924cf7c | 507 | mp_clear(k); |
wolfSSL | 15:117db924cf7c | 508 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 509 | XFREE(k, NULL, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 510 | #endif |
wolfSSL | 15:117db924cf7c | 511 | |
wolfSSL | 15:117db924cf7c | 512 | return ret; |
wolfSSL | 15:117db924cf7c | 513 | } |
wolfSSL | 15:117db924cf7c | 514 | |
wolfSSL | 15:117db924cf7c | 515 | |
wolfSSL | 15:117db924cf7c | 516 | #if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_PSS) |
wolfSSL | 15:117db924cf7c | 517 | /* Uses MGF1 standard as a mask generation function |
wolfSSL | 15:117db924cf7c | 518 | hType: hash type used |
wolfSSL | 15:117db924cf7c | 519 | seed: seed to use for generating mask |
wolfSSL | 15:117db924cf7c | 520 | seedSz: size of seed buffer |
wolfSSL | 15:117db924cf7c | 521 | out: mask output after generation |
wolfSSL | 15:117db924cf7c | 522 | outSz: size of output buffer |
wolfSSL | 15:117db924cf7c | 523 | */ |
wolfSSL | 15:117db924cf7c | 524 | static int RsaMGF1(enum wc_HashType hType, byte* seed, word32 seedSz, |
wolfSSL | 15:117db924cf7c | 525 | byte* out, word32 outSz, void* heap) |
wolfSSL | 15:117db924cf7c | 526 | { |
wolfSSL | 15:117db924cf7c | 527 | byte* tmp; |
wolfSSL | 15:117db924cf7c | 528 | /* needs to be large enough for seed size plus counter(4) */ |
wolfSSL | 15:117db924cf7c | 529 | byte tmpA[WC_MAX_DIGEST_SIZE + 4]; |
wolfSSL | 15:117db924cf7c | 530 | byte tmpF; /* 1 if dynamic memory needs freed */ |
wolfSSL | 15:117db924cf7c | 531 | word32 tmpSz; |
wolfSSL | 15:117db924cf7c | 532 | int hLen; |
wolfSSL | 15:117db924cf7c | 533 | int ret; |
wolfSSL | 15:117db924cf7c | 534 | word32 counter; |
wolfSSL | 15:117db924cf7c | 535 | word32 idx; |
wolfSSL | 15:117db924cf7c | 536 | hLen = wc_HashGetDigestSize(hType); |
wolfSSL | 15:117db924cf7c | 537 | counter = 0; |
wolfSSL | 15:117db924cf7c | 538 | idx = 0; |
wolfSSL | 15:117db924cf7c | 539 | |
wolfSSL | 15:117db924cf7c | 540 | (void)heap; |
wolfSSL | 15:117db924cf7c | 541 | |
wolfSSL | 15:117db924cf7c | 542 | /* check error return of wc_HashGetDigestSize */ |
wolfSSL | 15:117db924cf7c | 543 | if (hLen < 0) { |
wolfSSL | 15:117db924cf7c | 544 | return hLen; |
wolfSSL | 15:117db924cf7c | 545 | } |
wolfSSL | 15:117db924cf7c | 546 | |
wolfSSL | 15:117db924cf7c | 547 | /* if tmp is not large enough than use some dynamic memory */ |
wolfSSL | 15:117db924cf7c | 548 | if ((seedSz + 4) > sizeof(tmpA) || (word32)hLen > sizeof(tmpA)) { |
wolfSSL | 15:117db924cf7c | 549 | /* find largest amount of memory needed which will be the max of |
wolfSSL | 15:117db924cf7c | 550 | * hLen and (seedSz + 4) since tmp is used to store the hash digest */ |
wolfSSL | 15:117db924cf7c | 551 | tmpSz = ((seedSz + 4) > (word32)hLen)? seedSz + 4: (word32)hLen; |
wolfSSL | 15:117db924cf7c | 552 | tmp = (byte*)XMALLOC(tmpSz, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 553 | if (tmp == NULL) { |
wolfSSL | 15:117db924cf7c | 554 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 555 | } |
wolfSSL | 15:117db924cf7c | 556 | tmpF = 1; /* make sure to free memory when done */ |
wolfSSL | 15:117db924cf7c | 557 | } |
wolfSSL | 15:117db924cf7c | 558 | else { |
wolfSSL | 15:117db924cf7c | 559 | /* use array on the stack */ |
wolfSSL | 15:117db924cf7c | 560 | tmpSz = sizeof(tmpA); |
wolfSSL | 15:117db924cf7c | 561 | tmp = tmpA; |
wolfSSL | 15:117db924cf7c | 562 | tmpF = 0; /* no need to free memory at end */ |
wolfSSL | 15:117db924cf7c | 563 | } |
wolfSSL | 15:117db924cf7c | 564 | |
wolfSSL | 15:117db924cf7c | 565 | do { |
wolfSSL | 15:117db924cf7c | 566 | int i = 0; |
wolfSSL | 15:117db924cf7c | 567 | XMEMCPY(tmp, seed, seedSz); |
wolfSSL | 15:117db924cf7c | 568 | |
wolfSSL | 15:117db924cf7c | 569 | /* counter to byte array appended to tmp */ |
wolfSSL | 15:117db924cf7c | 570 | tmp[seedSz] = (counter >> 24) & 0xFF; |
wolfSSL | 15:117db924cf7c | 571 | tmp[seedSz + 1] = (counter >> 16) & 0xFF; |
wolfSSL | 15:117db924cf7c | 572 | tmp[seedSz + 2] = (counter >> 8) & 0xFF; |
wolfSSL | 15:117db924cf7c | 573 | tmp[seedSz + 3] = (counter) & 0xFF; |
wolfSSL | 15:117db924cf7c | 574 | |
wolfSSL | 15:117db924cf7c | 575 | /* hash and append to existing output */ |
wolfSSL | 15:117db924cf7c | 576 | if ((ret = wc_Hash(hType, tmp, (seedSz + 4), tmp, tmpSz)) != 0) { |
wolfSSL | 15:117db924cf7c | 577 | /* check for if dynamic memory was needed, then free */ |
wolfSSL | 15:117db924cf7c | 578 | if (tmpF) { |
wolfSSL | 15:117db924cf7c | 579 | XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 580 | } |
wolfSSL | 15:117db924cf7c | 581 | return ret; |
wolfSSL | 15:117db924cf7c | 582 | } |
wolfSSL | 15:117db924cf7c | 583 | |
wolfSSL | 15:117db924cf7c | 584 | for (i = 0; i < hLen && idx < outSz; i++) { |
wolfSSL | 15:117db924cf7c | 585 | out[idx++] = tmp[i]; |
wolfSSL | 15:117db924cf7c | 586 | } |
wolfSSL | 15:117db924cf7c | 587 | counter++; |
wolfSSL | 15:117db924cf7c | 588 | } while (idx < outSz); |
wolfSSL | 15:117db924cf7c | 589 | |
wolfSSL | 15:117db924cf7c | 590 | /* check for if dynamic memory was needed, then free */ |
wolfSSL | 15:117db924cf7c | 591 | if (tmpF) { |
wolfSSL | 15:117db924cf7c | 592 | XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 593 | } |
wolfSSL | 15:117db924cf7c | 594 | |
wolfSSL | 15:117db924cf7c | 595 | return 0; |
wolfSSL | 15:117db924cf7c | 596 | } |
wolfSSL | 15:117db924cf7c | 597 | |
wolfSSL | 15:117db924cf7c | 598 | /* helper function to direct which mask generation function is used |
wolfSSL | 15:117db924cf7c | 599 | switeched on type input |
wolfSSL | 15:117db924cf7c | 600 | */ |
wolfSSL | 15:117db924cf7c | 601 | static int RsaMGF(int type, byte* seed, word32 seedSz, byte* out, |
wolfSSL | 15:117db924cf7c | 602 | word32 outSz, void* heap) |
wolfSSL | 15:117db924cf7c | 603 | { |
wolfSSL | 15:117db924cf7c | 604 | int ret; |
wolfSSL | 15:117db924cf7c | 605 | |
wolfSSL | 15:117db924cf7c | 606 | switch(type) { |
wolfSSL | 15:117db924cf7c | 607 | #ifndef NO_SHA |
wolfSSL | 15:117db924cf7c | 608 | case WC_MGF1SHA1: |
wolfSSL | 15:117db924cf7c | 609 | ret = RsaMGF1(WC_HASH_TYPE_SHA, seed, seedSz, out, outSz, heap); |
wolfSSL | 15:117db924cf7c | 610 | break; |
wolfSSL | 15:117db924cf7c | 611 | #endif |
wolfSSL | 15:117db924cf7c | 612 | #ifndef NO_SHA256 |
wolfSSL | 15:117db924cf7c | 613 | #ifdef WOLFSSL_SHA224 |
wolfSSL | 15:117db924cf7c | 614 | case WC_MGF1SHA224: |
wolfSSL | 15:117db924cf7c | 615 | ret = RsaMGF1(WC_HASH_TYPE_SHA224, seed, seedSz, out, outSz, heap); |
wolfSSL | 15:117db924cf7c | 616 | break; |
wolfSSL | 15:117db924cf7c | 617 | #endif |
wolfSSL | 15:117db924cf7c | 618 | case WC_MGF1SHA256: |
wolfSSL | 15:117db924cf7c | 619 | ret = RsaMGF1(WC_HASH_TYPE_SHA256, seed, seedSz, out, outSz, heap); |
wolfSSL | 15:117db924cf7c | 620 | break; |
wolfSSL | 15:117db924cf7c | 621 | #endif |
wolfSSL | 15:117db924cf7c | 622 | #ifdef WOLFSSL_SHA384 |
wolfSSL | 15:117db924cf7c | 623 | case WC_MGF1SHA384: |
wolfSSL | 15:117db924cf7c | 624 | ret = RsaMGF1(WC_HASH_TYPE_SHA384, seed, seedSz, out, outSz, heap); |
wolfSSL | 15:117db924cf7c | 625 | break; |
wolfSSL | 15:117db924cf7c | 626 | #endif |
wolfSSL | 15:117db924cf7c | 627 | #ifdef WOLFSSL_SHA512 |
wolfSSL | 15:117db924cf7c | 628 | case WC_MGF1SHA512: |
wolfSSL | 15:117db924cf7c | 629 | ret = RsaMGF1(WC_HASH_TYPE_SHA512, seed, seedSz, out, outSz, heap); |
wolfSSL | 15:117db924cf7c | 630 | break; |
wolfSSL | 15:117db924cf7c | 631 | #endif |
wolfSSL | 15:117db924cf7c | 632 | default: |
wolfSSL | 15:117db924cf7c | 633 | WOLFSSL_MSG("Unknown MGF type: check build options"); |
wolfSSL | 15:117db924cf7c | 634 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 635 | } |
wolfSSL | 15:117db924cf7c | 636 | |
wolfSSL | 15:117db924cf7c | 637 | /* in case of default avoid unused warning */ |
wolfSSL | 15:117db924cf7c | 638 | (void)seed; |
wolfSSL | 15:117db924cf7c | 639 | (void)seedSz; |
wolfSSL | 15:117db924cf7c | 640 | (void)out; |
wolfSSL | 15:117db924cf7c | 641 | (void)outSz; |
wolfSSL | 15:117db924cf7c | 642 | (void)heap; |
wolfSSL | 15:117db924cf7c | 643 | |
wolfSSL | 15:117db924cf7c | 644 | return ret; |
wolfSSL | 15:117db924cf7c | 645 | } |
wolfSSL | 15:117db924cf7c | 646 | #endif /* !WC_NO_RSA_OAEP */ |
wolfSSL | 15:117db924cf7c | 647 | |
wolfSSL | 15:117db924cf7c | 648 | |
wolfSSL | 15:117db924cf7c | 649 | /* Padding */ |
wolfSSL | 15:117db924cf7c | 650 | #ifndef WC_NO_RSA_OAEP |
wolfSSL | 15:117db924cf7c | 651 | static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock, |
wolfSSL | 15:117db924cf7c | 652 | word32 pkcsBlockLen, byte padValue, WC_RNG* rng, |
wolfSSL | 15:117db924cf7c | 653 | enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen, |
wolfSSL | 15:117db924cf7c | 654 | void* heap) |
wolfSSL | 15:117db924cf7c | 655 | { |
wolfSSL | 15:117db924cf7c | 656 | int ret; |
wolfSSL | 15:117db924cf7c | 657 | int hLen; |
wolfSSL | 15:117db924cf7c | 658 | int psLen; |
wolfSSL | 15:117db924cf7c | 659 | int i; |
wolfSSL | 15:117db924cf7c | 660 | word32 idx; |
wolfSSL | 15:117db924cf7c | 661 | |
wolfSSL | 15:117db924cf7c | 662 | byte* dbMask; |
wolfSSL | 15:117db924cf7c | 663 | |
wolfSSL | 15:117db924cf7c | 664 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 665 | byte* lHash = NULL; |
wolfSSL | 15:117db924cf7c | 666 | byte* seed = NULL; |
wolfSSL | 15:117db924cf7c | 667 | #else |
wolfSSL | 15:117db924cf7c | 668 | /* must be large enough to contain largest hash */ |
wolfSSL | 15:117db924cf7c | 669 | byte lHash[WC_MAX_DIGEST_SIZE]; |
wolfSSL | 15:117db924cf7c | 670 | byte seed[ WC_MAX_DIGEST_SIZE]; |
wolfSSL | 15:117db924cf7c | 671 | #endif |
wolfSSL | 15:117db924cf7c | 672 | |
wolfSSL | 15:117db924cf7c | 673 | /* no label is allowed, but catch if no label provided and length > 0 */ |
wolfSSL | 15:117db924cf7c | 674 | if (optLabel == NULL && labelLen > 0) { |
wolfSSL | 15:117db924cf7c | 675 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 676 | } |
wolfSSL | 15:117db924cf7c | 677 | |
wolfSSL | 15:117db924cf7c | 678 | /* limit of label is the same as limit of hash function which is massive */ |
wolfSSL | 15:117db924cf7c | 679 | hLen = wc_HashGetDigestSize(hType); |
wolfSSL | 15:117db924cf7c | 680 | if (hLen < 0) { |
wolfSSL | 15:117db924cf7c | 681 | return hLen; |
wolfSSL | 15:117db924cf7c | 682 | } |
wolfSSL | 15:117db924cf7c | 683 | |
wolfSSL | 15:117db924cf7c | 684 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 685 | lHash = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 686 | if (lHash == NULL) { |
wolfSSL | 15:117db924cf7c | 687 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 688 | } |
wolfSSL | 15:117db924cf7c | 689 | seed = (byte*)XMALLOC(hLen, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 690 | if (seed == NULL) { |
wolfSSL | 15:117db924cf7c | 691 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 692 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 693 | } |
wolfSSL | 15:117db924cf7c | 694 | #else |
wolfSSL | 15:117db924cf7c | 695 | /* hLen should never be larger than lHash since size is max digest size, |
wolfSSL | 15:117db924cf7c | 696 | but check before blindly calling wc_Hash */ |
wolfSSL | 15:117db924cf7c | 697 | if ((word32)hLen > sizeof(lHash)) { |
wolfSSL | 15:117db924cf7c | 698 | WOLFSSL_MSG("OAEP lHash to small for digest!!"); |
wolfSSL | 15:117db924cf7c | 699 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 700 | } |
wolfSSL | 15:117db924cf7c | 701 | #endif |
wolfSSL | 15:117db924cf7c | 702 | |
wolfSSL | 15:117db924cf7c | 703 | if ((ret = wc_Hash(hType, optLabel, labelLen, lHash, hLen)) != 0) { |
wolfSSL | 15:117db924cf7c | 704 | WOLFSSL_MSG("OAEP hash type possibly not supported or lHash to small"); |
wolfSSL | 15:117db924cf7c | 705 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 706 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 707 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 708 | #endif |
wolfSSL | 15:117db924cf7c | 709 | return ret; |
wolfSSL | 15:117db924cf7c | 710 | } |
wolfSSL | 15:117db924cf7c | 711 | |
wolfSSL | 15:117db924cf7c | 712 | /* handles check of location for idx as well as psLen, cast to int to check |
wolfSSL | 15:117db924cf7c | 713 | for pkcsBlockLen(k) - 2 * hLen - 2 being negative |
wolfSSL | 15:117db924cf7c | 714 | This check is similar to decryption where k > 2 * hLen + 2 as msg |
wolfSSL | 15:117db924cf7c | 715 | size approaches 0. In decryption if k is less than or equal -- then there |
wolfSSL | 15:117db924cf7c | 716 | is no possible room for msg. |
wolfSSL | 15:117db924cf7c | 717 | k = RSA key size |
wolfSSL | 15:117db924cf7c | 718 | hLen = hash digest size -- will always be >= 0 at this point |
wolfSSL | 15:117db924cf7c | 719 | */ |
wolfSSL | 15:117db924cf7c | 720 | if ((word32)(2 * hLen + 2) > pkcsBlockLen) { |
wolfSSL | 15:117db924cf7c | 721 | WOLFSSL_MSG("OAEP pad error hash to big for RSA key size"); |
wolfSSL | 15:117db924cf7c | 722 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 723 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 724 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 725 | #endif |
wolfSSL | 15:117db924cf7c | 726 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 727 | } |
wolfSSL | 15:117db924cf7c | 728 | |
wolfSSL | 15:117db924cf7c | 729 | if (inputLen > (pkcsBlockLen - 2 * hLen - 2)) { |
wolfSSL | 15:117db924cf7c | 730 | WOLFSSL_MSG("OAEP pad error message too long"); |
wolfSSL | 15:117db924cf7c | 731 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 732 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 733 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 734 | #endif |
wolfSSL | 15:117db924cf7c | 735 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 736 | } |
wolfSSL | 15:117db924cf7c | 737 | |
wolfSSL | 15:117db924cf7c | 738 | /* concatenate lHash || PS || 0x01 || msg */ |
wolfSSL | 15:117db924cf7c | 739 | idx = pkcsBlockLen - 1 - inputLen; |
wolfSSL | 15:117db924cf7c | 740 | psLen = pkcsBlockLen - inputLen - 2 * hLen - 2; |
wolfSSL | 15:117db924cf7c | 741 | if (pkcsBlockLen < inputLen) { /*make sure not writing over end of buffer */ |
wolfSSL | 15:117db924cf7c | 742 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 743 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 744 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 745 | #endif |
wolfSSL | 15:117db924cf7c | 746 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 747 | } |
wolfSSL | 15:117db924cf7c | 748 | XMEMCPY(pkcsBlock + (pkcsBlockLen - inputLen), input, inputLen); |
wolfSSL | 15:117db924cf7c | 749 | pkcsBlock[idx--] = 0x01; /* PS and M separator */ |
wolfSSL | 15:117db924cf7c | 750 | while (psLen > 0 && idx > 0) { |
wolfSSL | 15:117db924cf7c | 751 | pkcsBlock[idx--] = 0x00; |
wolfSSL | 15:117db924cf7c | 752 | psLen--; |
wolfSSL | 15:117db924cf7c | 753 | } |
wolfSSL | 15:117db924cf7c | 754 | |
wolfSSL | 15:117db924cf7c | 755 | idx = idx - hLen + 1; |
wolfSSL | 15:117db924cf7c | 756 | XMEMCPY(pkcsBlock + idx, lHash, hLen); |
wolfSSL | 15:117db924cf7c | 757 | |
wolfSSL | 15:117db924cf7c | 758 | /* generate random seed */ |
wolfSSL | 15:117db924cf7c | 759 | if ((ret = wc_RNG_GenerateBlock(rng, seed, hLen)) != 0) { |
wolfSSL | 15:117db924cf7c | 760 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 761 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 762 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 763 | #endif |
wolfSSL | 15:117db924cf7c | 764 | return ret; |
wolfSSL | 15:117db924cf7c | 765 | } |
wolfSSL | 15:117db924cf7c | 766 | |
wolfSSL | 15:117db924cf7c | 767 | /* create maskedDB from dbMask */ |
wolfSSL | 15:117db924cf7c | 768 | dbMask = (byte*)XMALLOC(pkcsBlockLen - hLen - 1, heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 769 | if (dbMask == NULL) { |
wolfSSL | 15:117db924cf7c | 770 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 771 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 772 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 773 | #endif |
wolfSSL | 15:117db924cf7c | 774 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 775 | } |
wolfSSL | 15:117db924cf7c | 776 | XMEMSET(dbMask, 0, pkcsBlockLen - hLen - 1); /* help static analyzer */ |
wolfSSL | 15:117db924cf7c | 777 | |
wolfSSL | 15:117db924cf7c | 778 | ret = RsaMGF(mgf, seed, hLen, dbMask, pkcsBlockLen - hLen - 1, heap); |
wolfSSL | 15:117db924cf7c | 779 | if (ret != 0) { |
wolfSSL | 15:117db924cf7c | 780 | XFREE(dbMask, heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 781 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 782 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 783 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 784 | #endif |
wolfSSL | 15:117db924cf7c | 785 | return ret; |
wolfSSL | 15:117db924cf7c | 786 | } |
wolfSSL | 15:117db924cf7c | 787 | |
wolfSSL | 15:117db924cf7c | 788 | i = 0; |
wolfSSL | 15:117db924cf7c | 789 | idx = hLen + 1; |
wolfSSL | 15:117db924cf7c | 790 | while (idx < pkcsBlockLen && (word32)i < (pkcsBlockLen - hLen -1)) { |
wolfSSL | 15:117db924cf7c | 791 | pkcsBlock[idx] = dbMask[i++] ^ pkcsBlock[idx]; |
wolfSSL | 15:117db924cf7c | 792 | idx++; |
wolfSSL | 15:117db924cf7c | 793 | } |
wolfSSL | 15:117db924cf7c | 794 | XFREE(dbMask, heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 795 | |
wolfSSL | 15:117db924cf7c | 796 | |
wolfSSL | 15:117db924cf7c | 797 | /* create maskedSeed from seedMask */ |
wolfSSL | 15:117db924cf7c | 798 | idx = 0; |
wolfSSL | 15:117db924cf7c | 799 | pkcsBlock[idx++] = 0x00; |
wolfSSL | 15:117db924cf7c | 800 | /* create seedMask inline */ |
wolfSSL | 15:117db924cf7c | 801 | if ((ret = RsaMGF(mgf, pkcsBlock + hLen + 1, pkcsBlockLen - hLen - 1, |
wolfSSL | 15:117db924cf7c | 802 | pkcsBlock + 1, hLen, heap)) != 0) { |
wolfSSL | 15:117db924cf7c | 803 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 804 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 805 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 806 | #endif |
wolfSSL | 15:117db924cf7c | 807 | return ret; |
wolfSSL | 15:117db924cf7c | 808 | } |
wolfSSL | 15:117db924cf7c | 809 | |
wolfSSL | 15:117db924cf7c | 810 | /* xor created seedMask with seed to make maskedSeed */ |
wolfSSL | 15:117db924cf7c | 811 | i = 0; |
wolfSSL | 15:117db924cf7c | 812 | while (idx < (word32)(hLen + 1) && i < hLen) { |
wolfSSL | 15:117db924cf7c | 813 | pkcsBlock[idx] = pkcsBlock[idx] ^ seed[i++]; |
wolfSSL | 15:117db924cf7c | 814 | idx++; |
wolfSSL | 15:117db924cf7c | 815 | } |
wolfSSL | 15:117db924cf7c | 816 | |
wolfSSL | 15:117db924cf7c | 817 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 818 | XFREE(lHash, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 819 | XFREE(seed, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 820 | #endif |
wolfSSL | 15:117db924cf7c | 821 | (void)padValue; |
wolfSSL | 15:117db924cf7c | 822 | |
wolfSSL | 15:117db924cf7c | 823 | return 0; |
wolfSSL | 15:117db924cf7c | 824 | } |
wolfSSL | 15:117db924cf7c | 825 | #endif /* !WC_NO_RSA_OAEP */ |
wolfSSL | 15:117db924cf7c | 826 | |
wolfSSL | 15:117db924cf7c | 827 | #ifdef WC_RSA_PSS |
wolfSSL | 15:117db924cf7c | 828 | |
wolfSSL | 15:117db924cf7c | 829 | /* 0x00 .. 0x00 0x01 | Salt | Gen Hash | 0xbc |
wolfSSL | 15:117db924cf7c | 830 | * XOR MGF over all bytes down to end of Salt |
wolfSSL | 15:117db924cf7c | 831 | * Gen Hash = HASH(8 * 0x00 | Message Hash | Salt) |
wolfSSL | 15:117db924cf7c | 832 | * |
wolfSSL | 15:117db924cf7c | 833 | * input Digest of the message. |
wolfSSL | 15:117db924cf7c | 834 | * inputLen Length of digest. |
wolfSSL | 15:117db924cf7c | 835 | * pkcsBlock Buffer to write to. |
wolfSSL | 15:117db924cf7c | 836 | * pkcsBlockLen Length of buffer to write to. |
wolfSSL | 15:117db924cf7c | 837 | * rng Random number generator (for salt). |
wolfSSL | 15:117db924cf7c | 838 | * htype Hash function to use. |
wolfSSL | 15:117db924cf7c | 839 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 840 | * saltLen Length of salt to put in padding. |
wolfSSL | 15:117db924cf7c | 841 | * bits Length of key in bits. |
wolfSSL | 15:117db924cf7c | 842 | * heap Used for dynamic memory allocation. |
wolfSSL | 15:117db924cf7c | 843 | * returns 0 on success, PSS_SALTLEN_E when the salt length is invalid |
wolfSSL | 15:117db924cf7c | 844 | * and other negative values on error. |
wolfSSL | 15:117db924cf7c | 845 | */ |
wolfSSL | 15:117db924cf7c | 846 | static int RsaPad_PSS(const byte* input, word32 inputLen, byte* pkcsBlock, |
wolfSSL | 15:117db924cf7c | 847 | word32 pkcsBlockLen, WC_RNG* rng, enum wc_HashType hType, int mgf, |
wolfSSL | 15:117db924cf7c | 848 | int saltLen, int bits, void* heap) |
wolfSSL | 15:117db924cf7c | 849 | { |
wolfSSL | 15:117db924cf7c | 850 | int ret; |
wolfSSL | 15:117db924cf7c | 851 | int hLen, i; |
wolfSSL | 15:117db924cf7c | 852 | byte* s; |
wolfSSL | 15:117db924cf7c | 853 | byte* m; |
wolfSSL | 15:117db924cf7c | 854 | byte* h; |
wolfSSL | 15:117db924cf7c | 855 | byte salt[WC_MAX_DIGEST_SIZE]; |
wolfSSL | 15:117db924cf7c | 856 | |
wolfSSL | 15:117db924cf7c | 857 | hLen = wc_HashGetDigestSize(hType); |
wolfSSL | 15:117db924cf7c | 858 | if (hLen < 0) |
wolfSSL | 15:117db924cf7c | 859 | return hLen; |
wolfSSL | 15:117db924cf7c | 860 | |
wolfSSL | 15:117db924cf7c | 861 | if (saltLen == -1) { |
wolfSSL | 15:117db924cf7c | 862 | saltLen = hLen; |
wolfSSL | 15:117db924cf7c | 863 | #ifdef WOLFSSL_SHA512 |
wolfSSL | 15:117db924cf7c | 864 | /* See FIPS 186-4 section 5.5 item (e). */ |
wolfSSL | 15:117db924cf7c | 865 | if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE) |
wolfSSL | 15:117db924cf7c | 866 | saltLen = RSA_PSS_SALT_MAX_SZ; |
wolfSSL | 15:117db924cf7c | 867 | #endif |
wolfSSL | 15:117db924cf7c | 868 | } |
wolfSSL | 15:117db924cf7c | 869 | else if (saltLen > hLen || saltLen < -1) |
wolfSSL | 15:117db924cf7c | 870 | return PSS_SALTLEN_E; |
wolfSSL | 15:117db924cf7c | 871 | if ((int)pkcsBlockLen - hLen < saltLen + 2) |
wolfSSL | 15:117db924cf7c | 872 | return PSS_SALTLEN_E; |
wolfSSL | 15:117db924cf7c | 873 | |
wolfSSL | 15:117db924cf7c | 874 | s = m = pkcsBlock; |
wolfSSL | 15:117db924cf7c | 875 | XMEMSET(m, 0, RSA_PSS_PAD_SZ); |
wolfSSL | 15:117db924cf7c | 876 | m += RSA_PSS_PAD_SZ; |
wolfSSL | 15:117db924cf7c | 877 | XMEMCPY(m, input, inputLen); |
wolfSSL | 15:117db924cf7c | 878 | m += inputLen; |
wolfSSL | 15:117db924cf7c | 879 | if ((ret = wc_RNG_GenerateBlock(rng, salt, saltLen)) != 0) |
wolfSSL | 15:117db924cf7c | 880 | return ret; |
wolfSSL | 15:117db924cf7c | 881 | XMEMCPY(m, salt, saltLen); |
wolfSSL | 15:117db924cf7c | 882 | m += saltLen; |
wolfSSL | 15:117db924cf7c | 883 | |
wolfSSL | 15:117db924cf7c | 884 | h = pkcsBlock + pkcsBlockLen - 1 - hLen; |
wolfSSL | 15:117db924cf7c | 885 | if ((ret = wc_Hash(hType, s, (word32)(m - s), h, hLen)) != 0) |
wolfSSL | 15:117db924cf7c | 886 | return ret; |
wolfSSL | 15:117db924cf7c | 887 | pkcsBlock[pkcsBlockLen - 1] = RSA_PSS_PAD_TERM; |
wolfSSL | 15:117db924cf7c | 888 | |
wolfSSL | 15:117db924cf7c | 889 | ret = RsaMGF(mgf, h, hLen, pkcsBlock, pkcsBlockLen - hLen - 1, heap); |
wolfSSL | 15:117db924cf7c | 890 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 891 | return ret; |
wolfSSL | 15:117db924cf7c | 892 | pkcsBlock[0] &= (1 << ((bits - 1) & 0x7)) - 1; |
wolfSSL | 15:117db924cf7c | 893 | |
wolfSSL | 15:117db924cf7c | 894 | m = pkcsBlock + pkcsBlockLen - 1 - saltLen - hLen - 1; |
wolfSSL | 15:117db924cf7c | 895 | *(m++) ^= 0x01; |
wolfSSL | 15:117db924cf7c | 896 | for (i = 0; i < saltLen; i++) |
wolfSSL | 15:117db924cf7c | 897 | m[i] ^= salt[i]; |
wolfSSL | 15:117db924cf7c | 898 | |
wolfSSL | 15:117db924cf7c | 899 | return 0; |
wolfSSL | 15:117db924cf7c | 900 | } |
wolfSSL | 15:117db924cf7c | 901 | #endif |
wolfSSL | 15:117db924cf7c | 902 | |
wolfSSL | 15:117db924cf7c | 903 | static int RsaPad(const byte* input, word32 inputLen, byte* pkcsBlock, |
wolfSSL | 15:117db924cf7c | 904 | word32 pkcsBlockLen, byte padValue, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 905 | { |
wolfSSL | 15:117db924cf7c | 906 | if (input == NULL || inputLen == 0 || pkcsBlock == NULL || |
wolfSSL | 15:117db924cf7c | 907 | pkcsBlockLen == 0) { |
wolfSSL | 15:117db924cf7c | 908 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 909 | } |
wolfSSL | 15:117db924cf7c | 910 | |
wolfSSL | 15:117db924cf7c | 911 | pkcsBlock[0] = 0x0; /* set first byte to zero and advance */ |
wolfSSL | 15:117db924cf7c | 912 | pkcsBlock++; pkcsBlockLen--; |
wolfSSL | 15:117db924cf7c | 913 | pkcsBlock[0] = padValue; /* insert padValue */ |
wolfSSL | 15:117db924cf7c | 914 | |
wolfSSL | 15:117db924cf7c | 915 | if (padValue == RSA_BLOCK_TYPE_1) { |
wolfSSL | 15:117db924cf7c | 916 | if (pkcsBlockLen < inputLen + 2) { |
wolfSSL | 15:117db924cf7c | 917 | WOLFSSL_MSG("RsaPad error, invalid length"); |
wolfSSL | 15:117db924cf7c | 918 | return RSA_PAD_E; |
wolfSSL | 15:117db924cf7c | 919 | } |
wolfSSL | 15:117db924cf7c | 920 | |
wolfSSL | 15:117db924cf7c | 921 | /* pad with 0xff bytes */ |
wolfSSL | 15:117db924cf7c | 922 | XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2); |
wolfSSL | 15:117db924cf7c | 923 | } |
wolfSSL | 15:117db924cf7c | 924 | else { |
wolfSSL | 15:117db924cf7c | 925 | /* pad with non-zero random bytes */ |
wolfSSL | 15:117db924cf7c | 926 | word32 padLen, i; |
wolfSSL | 15:117db924cf7c | 927 | int ret; |
wolfSSL | 15:117db924cf7c | 928 | |
wolfSSL | 15:117db924cf7c | 929 | if (pkcsBlockLen < inputLen + 1) { |
wolfSSL | 15:117db924cf7c | 930 | WOLFSSL_MSG("RsaPad error, invalid length"); |
wolfSSL | 15:117db924cf7c | 931 | return RSA_PAD_E; |
wolfSSL | 15:117db924cf7c | 932 | } |
wolfSSL | 15:117db924cf7c | 933 | |
wolfSSL | 15:117db924cf7c | 934 | padLen = pkcsBlockLen - inputLen - 1; |
wolfSSL | 15:117db924cf7c | 935 | ret = wc_RNG_GenerateBlock(rng, &pkcsBlock[1], padLen); |
wolfSSL | 15:117db924cf7c | 936 | if (ret != 0) { |
wolfSSL | 15:117db924cf7c | 937 | return ret; |
wolfSSL | 15:117db924cf7c | 938 | } |
wolfSSL | 15:117db924cf7c | 939 | |
wolfSSL | 15:117db924cf7c | 940 | /* remove zeros */ |
wolfSSL | 15:117db924cf7c | 941 | for (i = 1; i < padLen; i++) { |
wolfSSL | 15:117db924cf7c | 942 | if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01; |
wolfSSL | 15:117db924cf7c | 943 | } |
wolfSSL | 15:117db924cf7c | 944 | } |
wolfSSL | 15:117db924cf7c | 945 | |
wolfSSL | 15:117db924cf7c | 946 | pkcsBlock[pkcsBlockLen-inputLen-1] = 0; /* separator */ |
wolfSSL | 15:117db924cf7c | 947 | XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen); |
wolfSSL | 15:117db924cf7c | 948 | |
wolfSSL | 15:117db924cf7c | 949 | return 0; |
wolfSSL | 15:117db924cf7c | 950 | } |
wolfSSL | 15:117db924cf7c | 951 | |
wolfSSL | 15:117db924cf7c | 952 | /* helper function to direct which padding is used */ |
wolfSSL | 15:117db924cf7c | 953 | static int wc_RsaPad_ex(const byte* input, word32 inputLen, byte* pkcsBlock, |
wolfSSL | 15:117db924cf7c | 954 | word32 pkcsBlockLen, byte padValue, WC_RNG* rng, int padType, |
wolfSSL | 15:117db924cf7c | 955 | enum wc_HashType hType, int mgf, byte* optLabel, word32 labelLen, |
wolfSSL | 15:117db924cf7c | 956 | int saltLen, int bits, void* heap) |
wolfSSL | 15:117db924cf7c | 957 | { |
wolfSSL | 15:117db924cf7c | 958 | int ret; |
wolfSSL | 15:117db924cf7c | 959 | |
wolfSSL | 15:117db924cf7c | 960 | switch (padType) |
wolfSSL | 15:117db924cf7c | 961 | { |
wolfSSL | 15:117db924cf7c | 962 | case WC_RSA_PKCSV15_PAD: |
wolfSSL | 15:117db924cf7c | 963 | /*WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 padding");*/ |
wolfSSL | 15:117db924cf7c | 964 | ret = RsaPad(input, inputLen, pkcsBlock, pkcsBlockLen, |
wolfSSL | 15:117db924cf7c | 965 | padValue, rng); |
wolfSSL | 15:117db924cf7c | 966 | break; |
wolfSSL | 15:117db924cf7c | 967 | |
wolfSSL | 15:117db924cf7c | 968 | #ifndef WC_NO_RSA_OAEP |
wolfSSL | 15:117db924cf7c | 969 | case WC_RSA_OAEP_PAD: |
wolfSSL | 15:117db924cf7c | 970 | WOLFSSL_MSG("wolfSSL Using RSA OAEP padding"); |
wolfSSL | 15:117db924cf7c | 971 | ret = RsaPad_OAEP(input, inputLen, pkcsBlock, pkcsBlockLen, |
wolfSSL | 15:117db924cf7c | 972 | padValue, rng, hType, mgf, optLabel, labelLen, heap); |
wolfSSL | 15:117db924cf7c | 973 | break; |
wolfSSL | 15:117db924cf7c | 974 | #endif |
wolfSSL | 15:117db924cf7c | 975 | |
wolfSSL | 15:117db924cf7c | 976 | #ifdef WC_RSA_PSS |
wolfSSL | 15:117db924cf7c | 977 | case WC_RSA_PSS_PAD: |
wolfSSL | 15:117db924cf7c | 978 | WOLFSSL_MSG("wolfSSL Using RSA PSS padding"); |
wolfSSL | 15:117db924cf7c | 979 | ret = RsaPad_PSS(input, inputLen, pkcsBlock, pkcsBlockLen, rng, |
wolfSSL | 15:117db924cf7c | 980 | hType, mgf, saltLen, bits, heap); |
wolfSSL | 15:117db924cf7c | 981 | break; |
wolfSSL | 15:117db924cf7c | 982 | #endif |
wolfSSL | 15:117db924cf7c | 983 | |
wolfSSL | 15:117db924cf7c | 984 | #ifdef WC_RSA_NO_PADDING |
wolfSSL | 15:117db924cf7c | 985 | case WC_RSA_NO_PAD: |
wolfSSL | 15:117db924cf7c | 986 | WOLFSSL_MSG("wolfSSL Using NO padding"); |
wolfSSL | 15:117db924cf7c | 987 | |
wolfSSL | 15:117db924cf7c | 988 | /* In the case of no padding being used check that input is exactly |
wolfSSL | 15:117db924cf7c | 989 | * the RSA key length */ |
wolfSSL | 15:117db924cf7c | 990 | if (bits <= 0 || inputLen != ((word32)bits/WOLFSSL_BIT_SIZE)) { |
wolfSSL | 15:117db924cf7c | 991 | WOLFSSL_MSG("Bad input size"); |
wolfSSL | 15:117db924cf7c | 992 | ret = RSA_PAD_E; |
wolfSSL | 15:117db924cf7c | 993 | } |
wolfSSL | 15:117db924cf7c | 994 | else { |
wolfSSL | 15:117db924cf7c | 995 | XMEMCPY(pkcsBlock, input, inputLen); |
wolfSSL | 15:117db924cf7c | 996 | ret = 0; |
wolfSSL | 15:117db924cf7c | 997 | } |
wolfSSL | 15:117db924cf7c | 998 | break; |
wolfSSL | 15:117db924cf7c | 999 | #endif |
wolfSSL | 15:117db924cf7c | 1000 | |
wolfSSL | 15:117db924cf7c | 1001 | default: |
wolfSSL | 15:117db924cf7c | 1002 | WOLFSSL_MSG("Unknown RSA Pad Type"); |
wolfSSL | 15:117db924cf7c | 1003 | ret = RSA_PAD_E; |
wolfSSL | 15:117db924cf7c | 1004 | } |
wolfSSL | 15:117db924cf7c | 1005 | |
wolfSSL | 15:117db924cf7c | 1006 | /* silence warning if not used with padding scheme */ |
wolfSSL | 15:117db924cf7c | 1007 | (void)hType; |
wolfSSL | 15:117db924cf7c | 1008 | (void)mgf; |
wolfSSL | 15:117db924cf7c | 1009 | (void)optLabel; |
wolfSSL | 15:117db924cf7c | 1010 | (void)labelLen; |
wolfSSL | 15:117db924cf7c | 1011 | (void)saltLen; |
wolfSSL | 15:117db924cf7c | 1012 | (void)bits; |
wolfSSL | 15:117db924cf7c | 1013 | (void)heap; |
wolfSSL | 15:117db924cf7c | 1014 | |
wolfSSL | 15:117db924cf7c | 1015 | return ret; |
wolfSSL | 15:117db924cf7c | 1016 | } |
wolfSSL | 15:117db924cf7c | 1017 | |
wolfSSL | 15:117db924cf7c | 1018 | |
wolfSSL | 15:117db924cf7c | 1019 | /* UnPadding */ |
wolfSSL | 15:117db924cf7c | 1020 | #ifndef WC_NO_RSA_OAEP |
wolfSSL | 15:117db924cf7c | 1021 | /* UnPad plaintext, set start to *output, return length of plaintext, |
wolfSSL | 15:117db924cf7c | 1022 | * < 0 on error */ |
wolfSSL | 15:117db924cf7c | 1023 | static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen, |
wolfSSL | 15:117db924cf7c | 1024 | byte **output, enum wc_HashType hType, int mgf, |
wolfSSL | 15:117db924cf7c | 1025 | byte* optLabel, word32 labelLen, void* heap) |
wolfSSL | 15:117db924cf7c | 1026 | { |
wolfSSL | 15:117db924cf7c | 1027 | int hLen; |
wolfSSL | 15:117db924cf7c | 1028 | int ret; |
wolfSSL | 15:117db924cf7c | 1029 | byte h[WC_MAX_DIGEST_SIZE]; /* max digest size */ |
wolfSSL | 15:117db924cf7c | 1030 | byte* tmp; |
wolfSSL | 15:117db924cf7c | 1031 | word32 idx; |
wolfSSL | 15:117db924cf7c | 1032 | |
wolfSSL | 15:117db924cf7c | 1033 | /* no label is allowed, but catch if no label provided and length > 0 */ |
wolfSSL | 15:117db924cf7c | 1034 | if (optLabel == NULL && labelLen > 0) { |
wolfSSL | 15:117db924cf7c | 1035 | return BUFFER_E; |
wolfSSL | 15:117db924cf7c | 1036 | } |
wolfSSL | 15:117db924cf7c | 1037 | |
wolfSSL | 15:117db924cf7c | 1038 | hLen = wc_HashGetDigestSize(hType); |
wolfSSL | 15:117db924cf7c | 1039 | if ((hLen < 0) || (pkcsBlockLen < (2 * (word32)hLen + 2))) { |
wolfSSL | 15:117db924cf7c | 1040 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1041 | } |
wolfSSL | 15:117db924cf7c | 1042 | |
wolfSSL | 15:117db924cf7c | 1043 | tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1044 | if (tmp == NULL) { |
wolfSSL | 15:117db924cf7c | 1045 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1046 | } |
wolfSSL | 15:117db924cf7c | 1047 | XMEMSET(tmp, 0, pkcsBlockLen); |
wolfSSL | 15:117db924cf7c | 1048 | |
wolfSSL | 15:117db924cf7c | 1049 | /* find seedMask value */ |
wolfSSL | 15:117db924cf7c | 1050 | if ((ret = RsaMGF(mgf, (byte*)(pkcsBlock + (hLen + 1)), |
wolfSSL | 15:117db924cf7c | 1051 | pkcsBlockLen - hLen - 1, tmp, hLen, heap)) != 0) { |
wolfSSL | 15:117db924cf7c | 1052 | XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1053 | return ret; |
wolfSSL | 15:117db924cf7c | 1054 | } |
wolfSSL | 15:117db924cf7c | 1055 | |
wolfSSL | 15:117db924cf7c | 1056 | /* xor seedMask value with maskedSeed to get seed value */ |
wolfSSL | 15:117db924cf7c | 1057 | for (idx = 0; idx < (word32)hLen; idx++) { |
wolfSSL | 15:117db924cf7c | 1058 | tmp[idx] = tmp[idx] ^ pkcsBlock[1 + idx]; |
wolfSSL | 15:117db924cf7c | 1059 | } |
wolfSSL | 15:117db924cf7c | 1060 | |
wolfSSL | 15:117db924cf7c | 1061 | /* get dbMask value */ |
wolfSSL | 15:117db924cf7c | 1062 | if ((ret = RsaMGF(mgf, tmp, hLen, tmp + hLen, |
wolfSSL | 15:117db924cf7c | 1063 | pkcsBlockLen - hLen - 1, heap)) != 0) { |
wolfSSL | 15:117db924cf7c | 1064 | XFREE(tmp, NULL, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1065 | return ret; |
wolfSSL | 15:117db924cf7c | 1066 | } |
wolfSSL | 15:117db924cf7c | 1067 | |
wolfSSL | 15:117db924cf7c | 1068 | /* get DB value by doing maskedDB xor dbMask */ |
wolfSSL | 15:117db924cf7c | 1069 | for (idx = 0; idx < (pkcsBlockLen - hLen - 1); idx++) { |
wolfSSL | 15:117db924cf7c | 1070 | pkcsBlock[hLen + 1 + idx] = pkcsBlock[hLen + 1 + idx] ^ tmp[idx + hLen]; |
wolfSSL | 15:117db924cf7c | 1071 | } |
wolfSSL | 15:117db924cf7c | 1072 | |
wolfSSL | 15:117db924cf7c | 1073 | /* done with use of tmp buffer */ |
wolfSSL | 15:117db924cf7c | 1074 | XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1075 | |
wolfSSL | 15:117db924cf7c | 1076 | /* advance idx to index of PS and msg separator, account for PS size of 0*/ |
wolfSSL | 15:117db924cf7c | 1077 | idx = hLen + 1 + hLen; |
wolfSSL | 15:117db924cf7c | 1078 | while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;} |
wolfSSL | 15:117db924cf7c | 1079 | |
wolfSSL | 15:117db924cf7c | 1080 | /* create hash of label for comparison with hash sent */ |
wolfSSL | 15:117db924cf7c | 1081 | if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) { |
wolfSSL | 15:117db924cf7c | 1082 | return ret; |
wolfSSL | 15:117db924cf7c | 1083 | } |
wolfSSL | 15:117db924cf7c | 1084 | |
wolfSSL | 15:117db924cf7c | 1085 | /* say no to chosen ciphertext attack. |
wolfSSL | 15:117db924cf7c | 1086 | Comparison of lHash, Y, and separator value needs to all happen in |
wolfSSL | 15:117db924cf7c | 1087 | constant time. |
wolfSSL | 15:117db924cf7c | 1088 | Attackers should not be able to get error condition from the timing of |
wolfSSL | 15:117db924cf7c | 1089 | these checks. |
wolfSSL | 15:117db924cf7c | 1090 | */ |
wolfSSL | 15:117db924cf7c | 1091 | ret = 0; |
wolfSSL | 15:117db924cf7c | 1092 | ret |= ConstantCompare(pkcsBlock + hLen + 1, h, hLen); |
wolfSSL | 15:117db924cf7c | 1093 | ret += pkcsBlock[idx++] ^ 0x01; /* separator value is 0x01 */ |
wolfSSL | 15:117db924cf7c | 1094 | ret += pkcsBlock[0] ^ 0x00; /* Y, the first value, should be 0 */ |
wolfSSL | 15:117db924cf7c | 1095 | |
wolfSSL | 15:117db924cf7c | 1096 | if (ret != 0) { |
wolfSSL | 15:117db924cf7c | 1097 | WOLFSSL_MSG("RsaUnPad_OAEP: Padding Error"); |
wolfSSL | 15:117db924cf7c | 1098 | return BAD_PADDING_E; |
wolfSSL | 15:117db924cf7c | 1099 | } |
wolfSSL | 15:117db924cf7c | 1100 | |
wolfSSL | 15:117db924cf7c | 1101 | /* adjust pointer to correct location in array and return size of M */ |
wolfSSL | 15:117db924cf7c | 1102 | *output = (byte*)(pkcsBlock + idx); |
wolfSSL | 15:117db924cf7c | 1103 | return pkcsBlockLen - idx; |
wolfSSL | 15:117db924cf7c | 1104 | } |
wolfSSL | 15:117db924cf7c | 1105 | #endif /* WC_NO_RSA_OAEP */ |
wolfSSL | 15:117db924cf7c | 1106 | |
wolfSSL | 15:117db924cf7c | 1107 | #ifdef WC_RSA_PSS |
wolfSSL | 15:117db924cf7c | 1108 | /* 0x00 .. 0x00 0x01 | Salt | Gen Hash | 0xbc |
wolfSSL | 15:117db924cf7c | 1109 | * MGF over all bytes down to end of Salt |
wolfSSL | 15:117db924cf7c | 1110 | * |
wolfSSL | 15:117db924cf7c | 1111 | * pkcsBlock Buffer holding decrypted data. |
wolfSSL | 15:117db924cf7c | 1112 | * pkcsBlockLen Length of buffer. |
wolfSSL | 15:117db924cf7c | 1113 | * htype Hash function to use. |
wolfSSL | 15:117db924cf7c | 1114 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 1115 | * saltLen Length of salt to put in padding. |
wolfSSL | 15:117db924cf7c | 1116 | * bits Length of key in bits. |
wolfSSL | 15:117db924cf7c | 1117 | * heap Used for dynamic memory allocation. |
wolfSSL | 15:117db924cf7c | 1118 | * returns 0 on success, PSS_SALTLEN_E when the salt length is invalid, |
wolfSSL | 15:117db924cf7c | 1119 | * BAD_PADDING_E when the padding is not valid, MEMORY_E when allocation fails |
wolfSSL | 15:117db924cf7c | 1120 | * and other negative values on error. |
wolfSSL | 15:117db924cf7c | 1121 | */ |
wolfSSL | 15:117db924cf7c | 1122 | static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen, |
wolfSSL | 15:117db924cf7c | 1123 | byte **output, enum wc_HashType hType, int mgf, |
wolfSSL | 15:117db924cf7c | 1124 | int saltLen, int bits, void* heap) |
wolfSSL | 15:117db924cf7c | 1125 | { |
wolfSSL | 15:117db924cf7c | 1126 | int ret; |
wolfSSL | 15:117db924cf7c | 1127 | byte* tmp; |
wolfSSL | 15:117db924cf7c | 1128 | int hLen, i; |
wolfSSL | 15:117db924cf7c | 1129 | |
wolfSSL | 15:117db924cf7c | 1130 | hLen = wc_HashGetDigestSize(hType); |
wolfSSL | 15:117db924cf7c | 1131 | if (hLen < 0) |
wolfSSL | 15:117db924cf7c | 1132 | return hLen; |
wolfSSL | 15:117db924cf7c | 1133 | |
wolfSSL | 15:117db924cf7c | 1134 | if (saltLen == -1) { |
wolfSSL | 15:117db924cf7c | 1135 | saltLen = hLen; |
wolfSSL | 15:117db924cf7c | 1136 | #ifdef WOLFSSL_SHA512 |
wolfSSL | 15:117db924cf7c | 1137 | /* See FIPS 186-4 section 5.5 item (e). */ |
wolfSSL | 15:117db924cf7c | 1138 | if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE) |
wolfSSL | 15:117db924cf7c | 1139 | saltLen = RSA_PSS_SALT_MAX_SZ; |
wolfSSL | 15:117db924cf7c | 1140 | #endif |
wolfSSL | 15:117db924cf7c | 1141 | } |
wolfSSL | 15:117db924cf7c | 1142 | else if (saltLen > hLen || saltLen < -1) |
wolfSSL | 15:117db924cf7c | 1143 | return PSS_SALTLEN_E; |
wolfSSL | 15:117db924cf7c | 1144 | if ((int)pkcsBlockLen - hLen < saltLen + 2) |
wolfSSL | 15:117db924cf7c | 1145 | return PSS_SALTLEN_E; |
wolfSSL | 15:117db924cf7c | 1146 | |
wolfSSL | 15:117db924cf7c | 1147 | if (pkcsBlock[pkcsBlockLen - 1] != RSA_PSS_PAD_TERM) { |
wolfSSL | 15:117db924cf7c | 1148 | WOLFSSL_MSG("RsaUnPad_PSS: Padding Term Error"); |
wolfSSL | 15:117db924cf7c | 1149 | return BAD_PADDING_E; |
wolfSSL | 15:117db924cf7c | 1150 | } |
wolfSSL | 15:117db924cf7c | 1151 | |
wolfSSL | 15:117db924cf7c | 1152 | tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1153 | if (tmp == NULL) |
wolfSSL | 15:117db924cf7c | 1154 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1155 | |
wolfSSL | 15:117db924cf7c | 1156 | if ((ret = RsaMGF(mgf, pkcsBlock + pkcsBlockLen - 1 - hLen, hLen, |
wolfSSL | 15:117db924cf7c | 1157 | tmp, pkcsBlockLen - 1 - hLen, heap)) != 0) { |
wolfSSL | 15:117db924cf7c | 1158 | XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1159 | return ret; |
wolfSSL | 15:117db924cf7c | 1160 | } |
wolfSSL | 15:117db924cf7c | 1161 | |
wolfSSL | 15:117db924cf7c | 1162 | tmp[0] &= (1 << ((bits - 1) & 0x7)) - 1; |
wolfSSL | 15:117db924cf7c | 1163 | for (i = 0; i < (int)(pkcsBlockLen - 1 - saltLen - hLen - 1); i++) { |
wolfSSL | 15:117db924cf7c | 1164 | if (tmp[i] != pkcsBlock[i]) { |
wolfSSL | 15:117db924cf7c | 1165 | XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1166 | WOLFSSL_MSG("RsaUnPad_PSS: Padding Error Match"); |
wolfSSL | 15:117db924cf7c | 1167 | return BAD_PADDING_E; |
wolfSSL | 15:117db924cf7c | 1168 | } |
wolfSSL | 15:117db924cf7c | 1169 | } |
wolfSSL | 15:117db924cf7c | 1170 | if (tmp[i] != (pkcsBlock[i] ^ 0x01)) { |
wolfSSL | 15:117db924cf7c | 1171 | XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1172 | WOLFSSL_MSG("RsaUnPad_PSS: Padding Error End"); |
wolfSSL | 15:117db924cf7c | 1173 | return BAD_PADDING_E; |
wolfSSL | 15:117db924cf7c | 1174 | } |
wolfSSL | 15:117db924cf7c | 1175 | for (i++; i < (int)(pkcsBlockLen - 1 - hLen); i++) |
wolfSSL | 15:117db924cf7c | 1176 | pkcsBlock[i] ^= tmp[i]; |
wolfSSL | 15:117db924cf7c | 1177 | |
wolfSSL | 15:117db924cf7c | 1178 | XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); |
wolfSSL | 15:117db924cf7c | 1179 | |
wolfSSL | 15:117db924cf7c | 1180 | *output = pkcsBlock + pkcsBlockLen - (hLen + saltLen + 1); |
wolfSSL | 15:117db924cf7c | 1181 | return saltLen + hLen; |
wolfSSL | 15:117db924cf7c | 1182 | } |
wolfSSL | 15:117db924cf7c | 1183 | #endif |
wolfSSL | 15:117db924cf7c | 1184 | |
wolfSSL | 15:117db924cf7c | 1185 | /* UnPad plaintext, set start to *output, return length of plaintext, |
wolfSSL | 15:117db924cf7c | 1186 | * < 0 on error */ |
wolfSSL | 15:117db924cf7c | 1187 | static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, |
wolfSSL | 15:117db924cf7c | 1188 | byte **output, byte padValue) |
wolfSSL | 15:117db924cf7c | 1189 | { |
wolfSSL | 15:117db924cf7c | 1190 | word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0; |
wolfSSL | 15:117db924cf7c | 1191 | word32 invalid = 0; |
wolfSSL | 15:117db924cf7c | 1192 | word32 i = 1; |
wolfSSL | 15:117db924cf7c | 1193 | word32 outputLen; |
wolfSSL | 15:117db924cf7c | 1194 | |
wolfSSL | 15:117db924cf7c | 1195 | if (output == NULL || pkcsBlockLen == 0) { |
wolfSSL | 15:117db924cf7c | 1196 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1197 | } |
wolfSSL | 15:117db924cf7c | 1198 | |
wolfSSL | 15:117db924cf7c | 1199 | if (pkcsBlock[0] != 0x0) { /* skip past zero */ |
wolfSSL | 15:117db924cf7c | 1200 | invalid = 1; |
wolfSSL | 15:117db924cf7c | 1201 | } |
wolfSSL | 15:117db924cf7c | 1202 | pkcsBlock++; pkcsBlockLen--; |
wolfSSL | 15:117db924cf7c | 1203 | |
wolfSSL | 15:117db924cf7c | 1204 | /* Require block type padValue */ |
wolfSSL | 15:117db924cf7c | 1205 | invalid = (pkcsBlock[0] != padValue) || invalid; |
wolfSSL | 15:117db924cf7c | 1206 | |
wolfSSL | 15:117db924cf7c | 1207 | /* verify the padding until we find the separator */ |
wolfSSL | 15:117db924cf7c | 1208 | if (padValue == RSA_BLOCK_TYPE_1) { |
wolfSSL | 15:117db924cf7c | 1209 | while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */} |
wolfSSL | 15:117db924cf7c | 1210 | } |
wolfSSL | 15:117db924cf7c | 1211 | else { |
wolfSSL | 15:117db924cf7c | 1212 | while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */} |
wolfSSL | 15:117db924cf7c | 1213 | } |
wolfSSL | 15:117db924cf7c | 1214 | |
wolfSSL | 15:117db924cf7c | 1215 | if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) { |
wolfSSL | 15:117db924cf7c | 1216 | WOLFSSL_MSG("RsaUnPad error, bad formatting"); |
wolfSSL | 15:117db924cf7c | 1217 | return RSA_PAD_E; |
wolfSSL | 15:117db924cf7c | 1218 | } |
wolfSSL | 15:117db924cf7c | 1219 | |
wolfSSL | 15:117db924cf7c | 1220 | outputLen = pkcsBlockLen - i; |
wolfSSL | 15:117db924cf7c | 1221 | invalid = (outputLen > maxOutputLen) || invalid; |
wolfSSL | 15:117db924cf7c | 1222 | |
wolfSSL | 15:117db924cf7c | 1223 | if (invalid) { |
wolfSSL | 15:117db924cf7c | 1224 | WOLFSSL_MSG("RsaUnPad error, invalid formatting"); |
wolfSSL | 15:117db924cf7c | 1225 | return RSA_PAD_E; |
wolfSSL | 15:117db924cf7c | 1226 | } |
wolfSSL | 15:117db924cf7c | 1227 | |
wolfSSL | 15:117db924cf7c | 1228 | *output = (byte *)(pkcsBlock + i); |
wolfSSL | 15:117db924cf7c | 1229 | return outputLen; |
wolfSSL | 15:117db924cf7c | 1230 | } |
wolfSSL | 15:117db924cf7c | 1231 | |
wolfSSL | 15:117db924cf7c | 1232 | /* helper function to direct unpadding |
wolfSSL | 15:117db924cf7c | 1233 | * |
wolfSSL | 15:117db924cf7c | 1234 | * bits is the key modulus size in bits |
wolfSSL | 15:117db924cf7c | 1235 | */ |
wolfSSL | 15:117db924cf7c | 1236 | static int wc_RsaUnPad_ex(byte* pkcsBlock, word32 pkcsBlockLen, byte** out, |
wolfSSL | 15:117db924cf7c | 1237 | byte padValue, int padType, enum wc_HashType hType, |
wolfSSL | 15:117db924cf7c | 1238 | int mgf, byte* optLabel, word32 labelLen, int saltLen, |
wolfSSL | 15:117db924cf7c | 1239 | int bits, void* heap) |
wolfSSL | 15:117db924cf7c | 1240 | { |
wolfSSL | 15:117db924cf7c | 1241 | int ret; |
wolfSSL | 15:117db924cf7c | 1242 | |
wolfSSL | 15:117db924cf7c | 1243 | switch (padType) { |
wolfSSL | 15:117db924cf7c | 1244 | case WC_RSA_PKCSV15_PAD: |
wolfSSL | 15:117db924cf7c | 1245 | /*WOLFSSL_MSG("wolfSSL Using RSA PKCSV15 un-padding");*/ |
wolfSSL | 15:117db924cf7c | 1246 | ret = RsaUnPad(pkcsBlock, pkcsBlockLen, out, padValue); |
wolfSSL | 15:117db924cf7c | 1247 | break; |
wolfSSL | 15:117db924cf7c | 1248 | |
wolfSSL | 15:117db924cf7c | 1249 | #ifndef WC_NO_RSA_OAEP |
wolfSSL | 15:117db924cf7c | 1250 | case WC_RSA_OAEP_PAD: |
wolfSSL | 15:117db924cf7c | 1251 | WOLFSSL_MSG("wolfSSL Using RSA OAEP un-padding"); |
wolfSSL | 15:117db924cf7c | 1252 | ret = RsaUnPad_OAEP((byte*)pkcsBlock, pkcsBlockLen, out, |
wolfSSL | 15:117db924cf7c | 1253 | hType, mgf, optLabel, labelLen, heap); |
wolfSSL | 15:117db924cf7c | 1254 | break; |
wolfSSL | 15:117db924cf7c | 1255 | #endif |
wolfSSL | 15:117db924cf7c | 1256 | |
wolfSSL | 15:117db924cf7c | 1257 | #ifdef WC_RSA_PSS |
wolfSSL | 15:117db924cf7c | 1258 | case WC_RSA_PSS_PAD: |
wolfSSL | 15:117db924cf7c | 1259 | WOLFSSL_MSG("wolfSSL Using RSA PSS un-padding"); |
wolfSSL | 15:117db924cf7c | 1260 | ret = RsaUnPad_PSS((byte*)pkcsBlock, pkcsBlockLen, out, hType, mgf, |
wolfSSL | 15:117db924cf7c | 1261 | saltLen, bits, heap); |
wolfSSL | 15:117db924cf7c | 1262 | break; |
wolfSSL | 15:117db924cf7c | 1263 | #endif |
wolfSSL | 15:117db924cf7c | 1264 | |
wolfSSL | 15:117db924cf7c | 1265 | #ifdef WC_RSA_NO_PADDING |
wolfSSL | 15:117db924cf7c | 1266 | case WC_RSA_NO_PAD: |
wolfSSL | 15:117db924cf7c | 1267 | WOLFSSL_MSG("wolfSSL Using NO un-padding"); |
wolfSSL | 15:117db924cf7c | 1268 | |
wolfSSL | 15:117db924cf7c | 1269 | /* In the case of no padding being used check that input is exactly |
wolfSSL | 15:117db924cf7c | 1270 | * the RSA key length */ |
wolfSSL | 15:117db924cf7c | 1271 | if (bits <= 0 || pkcsBlockLen != ((word32)bits/WOLFSSL_BIT_SIZE)) { |
wolfSSL | 15:117db924cf7c | 1272 | WOLFSSL_MSG("Bad input size"); |
wolfSSL | 15:117db924cf7c | 1273 | ret = RSA_PAD_E; |
wolfSSL | 15:117db924cf7c | 1274 | } |
wolfSSL | 15:117db924cf7c | 1275 | else { |
wolfSSL | 15:117db924cf7c | 1276 | if (out != NULL) { |
wolfSSL | 15:117db924cf7c | 1277 | *out = pkcsBlock; |
wolfSSL | 15:117db924cf7c | 1278 | } |
wolfSSL | 15:117db924cf7c | 1279 | ret = pkcsBlockLen; |
wolfSSL | 15:117db924cf7c | 1280 | } |
wolfSSL | 15:117db924cf7c | 1281 | break; |
wolfSSL | 15:117db924cf7c | 1282 | #endif /* WC_RSA_NO_PADDING */ |
wolfSSL | 15:117db924cf7c | 1283 | |
wolfSSL | 15:117db924cf7c | 1284 | default: |
wolfSSL | 15:117db924cf7c | 1285 | WOLFSSL_MSG("Unknown RSA UnPad Type"); |
wolfSSL | 15:117db924cf7c | 1286 | ret = RSA_PAD_E; |
wolfSSL | 15:117db924cf7c | 1287 | } |
wolfSSL | 15:117db924cf7c | 1288 | |
wolfSSL | 15:117db924cf7c | 1289 | /* silence warning if not used with padding scheme */ |
wolfSSL | 15:117db924cf7c | 1290 | (void)hType; |
wolfSSL | 15:117db924cf7c | 1291 | (void)mgf; |
wolfSSL | 15:117db924cf7c | 1292 | (void)optLabel; |
wolfSSL | 15:117db924cf7c | 1293 | (void)labelLen; |
wolfSSL | 15:117db924cf7c | 1294 | (void)saltLen; |
wolfSSL | 15:117db924cf7c | 1295 | (void)bits; |
wolfSSL | 15:117db924cf7c | 1296 | (void)heap; |
wolfSSL | 15:117db924cf7c | 1297 | |
wolfSSL | 15:117db924cf7c | 1298 | return ret; |
wolfSSL | 15:117db924cf7c | 1299 | } |
wolfSSL | 15:117db924cf7c | 1300 | |
wolfSSL | 15:117db924cf7c | 1301 | #if defined(WOLFSSL_XILINX_CRYPT) |
wolfSSL | 15:117db924cf7c | 1302 | /* |
wolfSSL | 15:117db924cf7c | 1303 | * Xilinx hardened crypto acceleration. |
wolfSSL | 15:117db924cf7c | 1304 | * |
wolfSSL | 15:117db924cf7c | 1305 | * Returns 0 on success and negative values on error. |
wolfSSL | 15:117db924cf7c | 1306 | */ |
wolfSSL | 15:117db924cf7c | 1307 | static int wc_RsaFunctionXil(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 1308 | word32* outLen, int type, RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 1309 | { |
wolfSSL | 15:117db924cf7c | 1310 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 1311 | word32 keyLen, len; |
wolfSSL | 15:117db924cf7c | 1312 | (void)rng; |
wolfSSL | 15:117db924cf7c | 1313 | |
wolfSSL | 15:117db924cf7c | 1314 | keyLen = wc_RsaEncryptSize(key); |
wolfSSL | 15:117db924cf7c | 1315 | if (keyLen > *outLen) { |
wolfSSL | 15:117db924cf7c | 1316 | WOLFSSL_MSG("Output buffer is not big enough"); |
wolfSSL | 15:117db924cf7c | 1317 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1318 | } |
wolfSSL | 15:117db924cf7c | 1319 | |
wolfSSL | 15:117db924cf7c | 1320 | if (inLen != keyLen) { |
wolfSSL | 15:117db924cf7c | 1321 | WOLFSSL_MSG("Expected that inLen equals RSA key length"); |
wolfSSL | 15:117db924cf7c | 1322 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1323 | } |
wolfSSL | 15:117db924cf7c | 1324 | |
wolfSSL | 15:117db924cf7c | 1325 | switch(type) { |
wolfSSL | 15:117db924cf7c | 1326 | case RSA_PRIVATE_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1327 | case RSA_PRIVATE_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1328 | /* Currently public exponent is loaded by default. |
wolfSSL | 15:117db924cf7c | 1329 | * In SDK 2017.1 RSA exponent values are expected to be of 4 bytes |
wolfSSL | 15:117db924cf7c | 1330 | * leading to private key operations with Xsecure_RsaDecrypt not being |
wolfSSL | 15:117db924cf7c | 1331 | * supported */ |
wolfSSL | 15:117db924cf7c | 1332 | ret = RSA_WRONG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 1333 | break; |
wolfSSL | 15:117db924cf7c | 1334 | case RSA_PUBLIC_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1335 | case RSA_PUBLIC_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1336 | if (XSecure_RsaDecrypt(&(key->xRsa), in, out) != XST_SUCCESS) { |
wolfSSL | 15:117db924cf7c | 1337 | ret = BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 1338 | } |
wolfSSL | 15:117db924cf7c | 1339 | break; |
wolfSSL | 15:117db924cf7c | 1340 | default: |
wolfSSL | 15:117db924cf7c | 1341 | ret = RSA_WRONG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 1342 | } |
wolfSSL | 15:117db924cf7c | 1343 | |
wolfSSL | 15:117db924cf7c | 1344 | *outLen = keyLen; |
wolfSSL | 15:117db924cf7c | 1345 | |
wolfSSL | 15:117db924cf7c | 1346 | return ret; |
wolfSSL | 15:117db924cf7c | 1347 | } |
wolfSSL | 15:117db924cf7c | 1348 | #endif /* WOLFSSL_XILINX_CRYPT */ |
wolfSSL | 15:117db924cf7c | 1349 | |
wolfSSL | 15:117db924cf7c | 1350 | static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 1351 | word32* outLen, int type, RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 1352 | { |
wolfSSL | 15:117db924cf7c | 1353 | #ifndef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 1354 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1355 | mp_int* tmp = NULL; |
wolfSSL | 15:117db924cf7c | 1356 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1357 | mp_int* rnd = NULL; |
wolfSSL | 15:117db924cf7c | 1358 | mp_int* rndi = NULL; |
wolfSSL | 15:117db924cf7c | 1359 | #endif |
wolfSSL | 15:117db924cf7c | 1360 | #else |
wolfSSL | 15:117db924cf7c | 1361 | mp_int tmp[1]; |
wolfSSL | 15:117db924cf7c | 1362 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1363 | mp_int rnd[1], rndi[1]; |
wolfSSL | 15:117db924cf7c | 1364 | #endif |
wolfSSL | 15:117db924cf7c | 1365 | #endif |
wolfSSL | 15:117db924cf7c | 1366 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 1367 | word32 keyLen, len; |
wolfSSL | 15:117db924cf7c | 1368 | #endif |
wolfSSL | 15:117db924cf7c | 1369 | |
wolfSSL | 15:117db924cf7c | 1370 | #ifdef WOLFSSL_HAVE_SP_RSA |
wolfSSL | 15:117db924cf7c | 1371 | #ifndef WOLFSSL_SP_NO_2048 |
wolfSSL | 15:117db924cf7c | 1372 | if (mp_count_bits(&key->n) == 2048) { |
wolfSSL | 15:117db924cf7c | 1373 | switch(type) { |
wolfSSL | 15:117db924cf7c | 1374 | case RSA_PRIVATE_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1375 | case RSA_PRIVATE_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1376 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1377 | if (rng == NULL) |
wolfSSL | 15:117db924cf7c | 1378 | return MISSING_RNG_E; |
wolfSSL | 15:117db924cf7c | 1379 | #endif |
wolfSSL | 15:117db924cf7c | 1380 | #ifndef RSA_LOW_MEM |
wolfSSL | 15:117db924cf7c | 1381 | return sp_RsaPrivate_2048(in, inLen, &key->d, &key->p, &key->q, |
wolfSSL | 15:117db924cf7c | 1382 | &key->dP, &key->dQ, &key->u, &key->n, |
wolfSSL | 15:117db924cf7c | 1383 | out, outLen); |
wolfSSL | 15:117db924cf7c | 1384 | #else |
wolfSSL | 15:117db924cf7c | 1385 | return sp_RsaPrivate_2048(in, inLen, &key->d, &key->p, &key->q, |
wolfSSL | 15:117db924cf7c | 1386 | NULL, NULL, NULL, &key->n, out, outLen); |
wolfSSL | 15:117db924cf7c | 1387 | #endif |
wolfSSL | 15:117db924cf7c | 1388 | case RSA_PUBLIC_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1389 | case RSA_PUBLIC_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1390 | return sp_RsaPublic_2048(in, inLen, &key->e, &key->n, out, outLen); |
wolfSSL | 15:117db924cf7c | 1391 | } |
wolfSSL | 15:117db924cf7c | 1392 | } |
wolfSSL | 15:117db924cf7c | 1393 | #endif |
wolfSSL | 15:117db924cf7c | 1394 | #ifndef WOLFSSL_SP_NO_3072 |
wolfSSL | 15:117db924cf7c | 1395 | if (mp_count_bits(&key->n) == 3072) { |
wolfSSL | 15:117db924cf7c | 1396 | switch(type) { |
wolfSSL | 15:117db924cf7c | 1397 | case RSA_PRIVATE_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1398 | case RSA_PRIVATE_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1399 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1400 | if (rng == NULL) |
wolfSSL | 15:117db924cf7c | 1401 | return MISSING_RNG_E; |
wolfSSL | 15:117db924cf7c | 1402 | #endif |
wolfSSL | 15:117db924cf7c | 1403 | #ifndef RSA_LOW_MEM |
wolfSSL | 15:117db924cf7c | 1404 | return sp_RsaPrivate_3072(in, inLen, &key->d, &key->p, &key->q, |
wolfSSL | 15:117db924cf7c | 1405 | &key->dP, &key->dQ, &key->u, &key->n, |
wolfSSL | 15:117db924cf7c | 1406 | out, outLen); |
wolfSSL | 15:117db924cf7c | 1407 | #else |
wolfSSL | 15:117db924cf7c | 1408 | return sp_RsaPrivate_3072(in, inLen, &key->d, &key->p, &key->q, |
wolfSSL | 15:117db924cf7c | 1409 | NULL, NULL, NULL, &key->n, out, outLen); |
wolfSSL | 15:117db924cf7c | 1410 | #endif |
wolfSSL | 15:117db924cf7c | 1411 | case RSA_PUBLIC_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1412 | case RSA_PUBLIC_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1413 | return sp_RsaPublic_3072(in, inLen, &key->e, &key->n, out, outLen); |
wolfSSL | 15:117db924cf7c | 1414 | } |
wolfSSL | 15:117db924cf7c | 1415 | } |
wolfSSL | 15:117db924cf7c | 1416 | #endif |
wolfSSL | 15:117db924cf7c | 1417 | #endif /* WOLFSSL_HAVE_SP_RSA */ |
wolfSSL | 15:117db924cf7c | 1418 | |
wolfSSL | 15:117db924cf7c | 1419 | #ifdef WOLFSSL_SP_MATH |
wolfSSL | 15:117db924cf7c | 1420 | return WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 1421 | #else |
wolfSSL | 15:117db924cf7c | 1422 | (void)rng; |
wolfSSL | 15:117db924cf7c | 1423 | |
wolfSSL | 15:117db924cf7c | 1424 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1425 | tmp = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1426 | if (tmp == NULL) |
wolfSSL | 15:117db924cf7c | 1427 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1428 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1429 | rnd = (mp_int*)XMALLOC(sizeof(mp_int) * 2, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1430 | if (rnd == NULL) { |
wolfSSL | 15:117db924cf7c | 1431 | XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1432 | return MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1433 | } |
wolfSSL | 15:117db924cf7c | 1434 | rndi = rnd + 1; |
wolfSSL | 15:117db924cf7c | 1435 | #endif /* WC_RSA_BLINDING */ |
wolfSSL | 15:117db924cf7c | 1436 | #endif /* WOLFSSL_SMALL_STACK */ |
wolfSSL | 15:117db924cf7c | 1437 | |
wolfSSL | 15:117db924cf7c | 1438 | if (mp_init(tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1439 | ret = MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 1440 | |
wolfSSL | 15:117db924cf7c | 1441 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1442 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1443 | if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) { |
wolfSSL | 15:117db924cf7c | 1444 | if (mp_init_multi(rnd, rndi, NULL, NULL, NULL, NULL) != MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 1445 | mp_clear(tmp); |
wolfSSL | 15:117db924cf7c | 1446 | ret = MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 1447 | } |
wolfSSL | 15:117db924cf7c | 1448 | } |
wolfSSL | 15:117db924cf7c | 1449 | } |
wolfSSL | 15:117db924cf7c | 1450 | #endif |
wolfSSL | 15:117db924cf7c | 1451 | |
wolfSSL | 15:117db924cf7c | 1452 | if (ret == 0 && mp_read_unsigned_bin(tmp, (byte*)in, inLen) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1453 | ret = MP_READ_E; |
wolfSSL | 15:117db924cf7c | 1454 | |
wolfSSL | 15:117db924cf7c | 1455 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1456 | switch(type) { |
wolfSSL | 15:117db924cf7c | 1457 | case RSA_PRIVATE_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1458 | case RSA_PRIVATE_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1459 | { |
wolfSSL | 15:117db924cf7c | 1460 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1461 | /* blind */ |
wolfSSL | 15:117db924cf7c | 1462 | ret = mp_rand(rnd, get_digit_count(&key->n), rng); |
wolfSSL | 15:117db924cf7c | 1463 | |
wolfSSL | 15:117db924cf7c | 1464 | /* rndi = 1/rnd mod n */ |
wolfSSL | 15:117db924cf7c | 1465 | if (ret == 0 && mp_invmod(rnd, &key->n, rndi) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1466 | ret = MP_INVMOD_E; |
wolfSSL | 15:117db924cf7c | 1467 | |
wolfSSL | 15:117db924cf7c | 1468 | /* rnd = rnd^e */ |
wolfSSL | 15:117db924cf7c | 1469 | if (ret == 0 && mp_exptmod(rnd, &key->e, &key->n, rnd) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1470 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 1471 | |
wolfSSL | 15:117db924cf7c | 1472 | /* tmp = tmp*rnd mod n */ |
wolfSSL | 15:117db924cf7c | 1473 | if (ret == 0 && mp_mulmod(tmp, rnd, &key->n, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1474 | ret = MP_MULMOD_E; |
wolfSSL | 15:117db924cf7c | 1475 | #endif /* WC_RSA_BLINDING */ |
wolfSSL | 15:117db924cf7c | 1476 | |
wolfSSL | 15:117db924cf7c | 1477 | #ifdef RSA_LOW_MEM /* half as much memory but twice as slow */ |
wolfSSL | 15:117db924cf7c | 1478 | if (ret == 0 && mp_exptmod(tmp, &key->d, &key->n, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1479 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 1480 | #else |
wolfSSL | 15:117db924cf7c | 1481 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1482 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1483 | mp_int* tmpa = NULL; |
wolfSSL | 15:117db924cf7c | 1484 | mp_int* tmpb = NULL; |
wolfSSL | 15:117db924cf7c | 1485 | #else |
wolfSSL | 15:117db924cf7c | 1486 | mp_int tmpa[1], tmpb[1]; |
wolfSSL | 15:117db924cf7c | 1487 | #endif |
wolfSSL | 15:117db924cf7c | 1488 | int cleara = 0, clearb = 0; |
wolfSSL | 15:117db924cf7c | 1489 | |
wolfSSL | 15:117db924cf7c | 1490 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1491 | tmpa = XMALLOC(sizeof(mp_int) * 2, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1492 | if (tmpa != NULL) |
wolfSSL | 15:117db924cf7c | 1493 | tmpb = tmpa + 1; |
wolfSSL | 15:117db924cf7c | 1494 | else |
wolfSSL | 15:117db924cf7c | 1495 | ret = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1496 | #endif |
wolfSSL | 15:117db924cf7c | 1497 | |
wolfSSL | 15:117db924cf7c | 1498 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1499 | if (mp_init(tmpa) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1500 | ret = MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 1501 | else |
wolfSSL | 15:117db924cf7c | 1502 | cleara = 1; |
wolfSSL | 15:117db924cf7c | 1503 | } |
wolfSSL | 15:117db924cf7c | 1504 | |
wolfSSL | 15:117db924cf7c | 1505 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1506 | if (mp_init(tmpb) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1507 | ret = MP_INIT_E; |
wolfSSL | 15:117db924cf7c | 1508 | else |
wolfSSL | 15:117db924cf7c | 1509 | clearb = 1; |
wolfSSL | 15:117db924cf7c | 1510 | } |
wolfSSL | 15:117db924cf7c | 1511 | |
wolfSSL | 15:117db924cf7c | 1512 | /* tmpa = tmp^dP mod p */ |
wolfSSL | 15:117db924cf7c | 1513 | if (ret == 0 && mp_exptmod(tmp, &key->dP, &key->p, |
wolfSSL | 15:117db924cf7c | 1514 | tmpa) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1515 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 1516 | |
wolfSSL | 15:117db924cf7c | 1517 | /* tmpb = tmp^dQ mod q */ |
wolfSSL | 15:117db924cf7c | 1518 | if (ret == 0 && mp_exptmod(tmp, &key->dQ, &key->q, |
wolfSSL | 15:117db924cf7c | 1519 | tmpb) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1520 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 1521 | |
wolfSSL | 15:117db924cf7c | 1522 | /* tmp = (tmpa - tmpb) * qInv (mod p) */ |
wolfSSL | 15:117db924cf7c | 1523 | if (ret == 0 && mp_sub(tmpa, tmpb, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1524 | ret = MP_SUB_E; |
wolfSSL | 15:117db924cf7c | 1525 | |
wolfSSL | 15:117db924cf7c | 1526 | if (ret == 0 && mp_mulmod(tmp, &key->u, &key->p, |
wolfSSL | 15:117db924cf7c | 1527 | tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1528 | ret = MP_MULMOD_E; |
wolfSSL | 15:117db924cf7c | 1529 | |
wolfSSL | 15:117db924cf7c | 1530 | /* tmp = tmpb + q * tmp */ |
wolfSSL | 15:117db924cf7c | 1531 | if (ret == 0 && mp_mul(tmp, &key->q, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1532 | ret = MP_MUL_E; |
wolfSSL | 15:117db924cf7c | 1533 | |
wolfSSL | 15:117db924cf7c | 1534 | if (ret == 0 && mp_add(tmp, tmpb, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1535 | ret = MP_ADD_E; |
wolfSSL | 15:117db924cf7c | 1536 | |
wolfSSL | 15:117db924cf7c | 1537 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1538 | if (tmpa != NULL) |
wolfSSL | 15:117db924cf7c | 1539 | #endif |
wolfSSL | 15:117db924cf7c | 1540 | { |
wolfSSL | 15:117db924cf7c | 1541 | if (cleara) |
wolfSSL | 15:117db924cf7c | 1542 | mp_clear(tmpa); |
wolfSSL | 15:117db924cf7c | 1543 | if (clearb) |
wolfSSL | 15:117db924cf7c | 1544 | mp_clear(tmpb); |
wolfSSL | 15:117db924cf7c | 1545 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1546 | XFREE(tmpa, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1547 | #endif |
wolfSSL | 15:117db924cf7c | 1548 | } |
wolfSSL | 15:117db924cf7c | 1549 | } /* tmpa/b scope */ |
wolfSSL | 15:117db924cf7c | 1550 | #endif /* RSA_LOW_MEM */ |
wolfSSL | 15:117db924cf7c | 1551 | |
wolfSSL | 15:117db924cf7c | 1552 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1553 | /* unblind */ |
wolfSSL | 15:117db924cf7c | 1554 | if (ret == 0 && mp_mulmod(tmp, rndi, &key->n, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1555 | ret = MP_MULMOD_E; |
wolfSSL | 15:117db924cf7c | 1556 | #endif /* WC_RSA_BLINDING */ |
wolfSSL | 15:117db924cf7c | 1557 | |
wolfSSL | 15:117db924cf7c | 1558 | break; |
wolfSSL | 15:117db924cf7c | 1559 | } |
wolfSSL | 15:117db924cf7c | 1560 | case RSA_PUBLIC_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1561 | case RSA_PUBLIC_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1562 | #ifdef WOLFSSL_XILINX_CRYPT |
wolfSSL | 15:117db924cf7c | 1563 | ret = wc_RsaFunctionXil(in, inLen, out, outLen, type, key, rng); |
wolfSSL | 15:117db924cf7c | 1564 | #else |
wolfSSL | 15:117db924cf7c | 1565 | if (mp_exptmod(tmp, &key->e, &key->n, tmp) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1566 | ret = MP_EXPTMOD_E; |
wolfSSL | 15:117db924cf7c | 1567 | break; |
wolfSSL | 15:117db924cf7c | 1568 | #endif |
wolfSSL | 15:117db924cf7c | 1569 | default: |
wolfSSL | 15:117db924cf7c | 1570 | ret = RSA_WRONG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 1571 | break; |
wolfSSL | 15:117db924cf7c | 1572 | } |
wolfSSL | 15:117db924cf7c | 1573 | } |
wolfSSL | 15:117db924cf7c | 1574 | |
wolfSSL | 15:117db924cf7c | 1575 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1576 | keyLen = wc_RsaEncryptSize(key); |
wolfSSL | 15:117db924cf7c | 1577 | if (keyLen > *outLen) |
wolfSSL | 15:117db924cf7c | 1578 | ret = RSA_BUFFER_E; |
wolfSSL | 15:117db924cf7c | 1579 | } |
wolfSSL | 15:117db924cf7c | 1580 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1581 | len = mp_unsigned_bin_size(tmp); |
wolfSSL | 15:117db924cf7c | 1582 | |
wolfSSL | 15:117db924cf7c | 1583 | /* pad front w/ zeros to match key length */ |
wolfSSL | 15:117db924cf7c | 1584 | while (len < keyLen) { |
wolfSSL | 15:117db924cf7c | 1585 | *out++ = 0x00; |
wolfSSL | 15:117db924cf7c | 1586 | len++; |
wolfSSL | 15:117db924cf7c | 1587 | } |
wolfSSL | 15:117db924cf7c | 1588 | |
wolfSSL | 15:117db924cf7c | 1589 | *outLen = keyLen; |
wolfSSL | 15:117db924cf7c | 1590 | |
wolfSSL | 15:117db924cf7c | 1591 | /* convert */ |
wolfSSL | 15:117db924cf7c | 1592 | if (mp_to_unsigned_bin(tmp, out) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1593 | ret = MP_TO_E; |
wolfSSL | 15:117db924cf7c | 1594 | } |
wolfSSL | 15:117db924cf7c | 1595 | |
wolfSSL | 15:117db924cf7c | 1596 | mp_clear(tmp); |
wolfSSL | 15:117db924cf7c | 1597 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1598 | XFREE(tmp, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1599 | #endif |
wolfSSL | 15:117db924cf7c | 1600 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 1601 | if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) { |
wolfSSL | 15:117db924cf7c | 1602 | mp_clear(rndi); |
wolfSSL | 15:117db924cf7c | 1603 | mp_clear(rnd); |
wolfSSL | 15:117db924cf7c | 1604 | } |
wolfSSL | 15:117db924cf7c | 1605 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1606 | XFREE(rnd, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1607 | #endif |
wolfSSL | 15:117db924cf7c | 1608 | #endif /* WC_RSA_BLINDING */ |
wolfSSL | 15:117db924cf7c | 1609 | return ret; |
wolfSSL | 15:117db924cf7c | 1610 | #endif /* WOLFSSL_SP_MATH */ |
wolfSSL | 15:117db924cf7c | 1611 | } |
wolfSSL | 15:117db924cf7c | 1612 | |
wolfSSL | 15:117db924cf7c | 1613 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) |
wolfSSL | 15:117db924cf7c | 1614 | static int wc_RsaFunctionAsync(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 1615 | word32* outLen, int type, RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 1616 | { |
wolfSSL | 15:117db924cf7c | 1617 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 1618 | |
wolfSSL | 15:117db924cf7c | 1619 | (void)rng; |
wolfSSL | 15:117db924cf7c | 1620 | |
wolfSSL | 15:117db924cf7c | 1621 | #ifdef WOLFSSL_ASYNC_CRYPT_TEST |
wolfSSL | 15:117db924cf7c | 1622 | if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_RSA_FUNC)) { |
wolfSSL | 15:117db924cf7c | 1623 | WC_ASYNC_TEST* testDev = &key->asyncDev.test; |
wolfSSL | 15:117db924cf7c | 1624 | testDev->rsaFunc.in = in; |
wolfSSL | 15:117db924cf7c | 1625 | testDev->rsaFunc.inSz = inLen; |
wolfSSL | 15:117db924cf7c | 1626 | testDev->rsaFunc.out = out; |
wolfSSL | 15:117db924cf7c | 1627 | testDev->rsaFunc.outSz = outLen; |
wolfSSL | 15:117db924cf7c | 1628 | testDev->rsaFunc.type = type; |
wolfSSL | 15:117db924cf7c | 1629 | testDev->rsaFunc.key = key; |
wolfSSL | 15:117db924cf7c | 1630 | testDev->rsaFunc.rng = rng; |
wolfSSL | 15:117db924cf7c | 1631 | return WC_PENDING_E; |
wolfSSL | 15:117db924cf7c | 1632 | } |
wolfSSL | 15:117db924cf7c | 1633 | #endif /* WOLFSSL_ASYNC_CRYPT_TEST */ |
wolfSSL | 15:117db924cf7c | 1634 | |
wolfSSL | 15:117db924cf7c | 1635 | switch(type) { |
wolfSSL | 15:117db924cf7c | 1636 | case RSA_PRIVATE_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1637 | case RSA_PRIVATE_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1638 | #ifdef HAVE_CAVIUM |
wolfSSL | 15:117db924cf7c | 1639 | key->dataLen = key->n.raw.len; |
wolfSSL | 15:117db924cf7c | 1640 | ret = NitroxRsaExptMod(in, inLen, |
wolfSSL | 15:117db924cf7c | 1641 | key->d.raw.buf, key->d.raw.len, |
wolfSSL | 15:117db924cf7c | 1642 | key->n.raw.buf, key->n.raw.len, |
wolfSSL | 15:117db924cf7c | 1643 | out, outLen, key); |
wolfSSL | 15:117db924cf7c | 1644 | #elif defined(HAVE_INTEL_QA) |
wolfSSL | 15:117db924cf7c | 1645 | #ifdef RSA_LOW_MEM |
wolfSSL | 15:117db924cf7c | 1646 | ret = IntelQaRsaPrivate(&key->asyncDev, in, inLen, |
wolfSSL | 15:117db924cf7c | 1647 | &key->d.raw, &key->n.raw, |
wolfSSL | 15:117db924cf7c | 1648 | out, outLen); |
wolfSSL | 15:117db924cf7c | 1649 | #else |
wolfSSL | 15:117db924cf7c | 1650 | ret = IntelQaRsaCrtPrivate(&key->asyncDev, in, inLen, |
wolfSSL | 15:117db924cf7c | 1651 | &key->p.raw, &key->q.raw, |
wolfSSL | 15:117db924cf7c | 1652 | &key->dP.raw, &key->dQ.raw, |
wolfSSL | 15:117db924cf7c | 1653 | &key->u.raw, |
wolfSSL | 15:117db924cf7c | 1654 | out, outLen); |
wolfSSL | 15:117db924cf7c | 1655 | #endif |
wolfSSL | 15:117db924cf7c | 1656 | #else /* WOLFSSL_ASYNC_CRYPT_TEST */ |
wolfSSL | 15:117db924cf7c | 1657 | ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng); |
wolfSSL | 15:117db924cf7c | 1658 | #endif |
wolfSSL | 15:117db924cf7c | 1659 | break; |
wolfSSL | 15:117db924cf7c | 1660 | |
wolfSSL | 15:117db924cf7c | 1661 | case RSA_PUBLIC_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1662 | case RSA_PUBLIC_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1663 | #ifdef HAVE_CAVIUM |
wolfSSL | 15:117db924cf7c | 1664 | key->dataLen = key->n.raw.len; |
wolfSSL | 15:117db924cf7c | 1665 | ret = NitroxRsaExptMod(in, inLen, |
wolfSSL | 15:117db924cf7c | 1666 | key->e.raw.buf, key->e.raw.len, |
wolfSSL | 15:117db924cf7c | 1667 | key->n.raw.buf, key->n.raw.len, |
wolfSSL | 15:117db924cf7c | 1668 | out, outLen, key); |
wolfSSL | 15:117db924cf7c | 1669 | #elif defined(HAVE_INTEL_QA) |
wolfSSL | 15:117db924cf7c | 1670 | ret = IntelQaRsaPublic(&key->asyncDev, in, inLen, |
wolfSSL | 15:117db924cf7c | 1671 | &key->e.raw, &key->n.raw, |
wolfSSL | 15:117db924cf7c | 1672 | out, outLen); |
wolfSSL | 15:117db924cf7c | 1673 | #else /* WOLFSSL_ASYNC_CRYPT_TEST */ |
wolfSSL | 15:117db924cf7c | 1674 | ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng); |
wolfSSL | 15:117db924cf7c | 1675 | #endif |
wolfSSL | 15:117db924cf7c | 1676 | break; |
wolfSSL | 15:117db924cf7c | 1677 | |
wolfSSL | 15:117db924cf7c | 1678 | default: |
wolfSSL | 15:117db924cf7c | 1679 | ret = RSA_WRONG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 1680 | } |
wolfSSL | 15:117db924cf7c | 1681 | |
wolfSSL | 15:117db924cf7c | 1682 | return ret; |
wolfSSL | 15:117db924cf7c | 1683 | } |
wolfSSL | 15:117db924cf7c | 1684 | #endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_RSA */ |
wolfSSL | 15:117db924cf7c | 1685 | |
wolfSSL | 15:117db924cf7c | 1686 | #if defined(WC_RSA_DIRECT) || defined(WC_RSA_NO_PADDING) |
wolfSSL | 15:117db924cf7c | 1687 | /* Function that does the RSA operation directly with no padding. |
wolfSSL | 15:117db924cf7c | 1688 | * |
wolfSSL | 15:117db924cf7c | 1689 | * in buffer to do operation on |
wolfSSL | 15:117db924cf7c | 1690 | * inLen length of input buffer |
wolfSSL | 15:117db924cf7c | 1691 | * out buffer to hold results |
wolfSSL | 15:117db924cf7c | 1692 | * outSz gets set to size of result buffer. Should be passed in as length |
wolfSSL | 15:117db924cf7c | 1693 | * of out buffer. If the pointer "out" is null then outSz gets set to |
wolfSSL | 15:117db924cf7c | 1694 | * the expected buffer size needed and LENGTH_ONLY_E gets returned. |
wolfSSL | 15:117db924cf7c | 1695 | * key RSA key to use for encrypt/decrypt |
wolfSSL | 15:117db924cf7c | 1696 | * type if using private or public key {RSA_PUBLIC_ENCRYPT, |
wolfSSL | 15:117db924cf7c | 1697 | * RSA_PUBLIC_DECRYPT, RSA_PRIVATE_ENCRYPT, RSA_PRIVATE_DECRYPT} |
wolfSSL | 15:117db924cf7c | 1698 | * rng wolfSSL RNG to use if needed |
wolfSSL | 15:117db924cf7c | 1699 | * |
wolfSSL | 15:117db924cf7c | 1700 | * returns size of result on success |
wolfSSL | 15:117db924cf7c | 1701 | */ |
wolfSSL | 15:117db924cf7c | 1702 | int wc_RsaDirect(byte* in, word32 inLen, byte* out, word32* outSz, |
wolfSSL | 15:117db924cf7c | 1703 | RsaKey* key, int type, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 1704 | { |
wolfSSL | 15:117db924cf7c | 1705 | int ret; |
wolfSSL | 15:117db924cf7c | 1706 | |
wolfSSL | 15:117db924cf7c | 1707 | if (in == NULL || outSz == NULL || key == NULL) { |
wolfSSL | 15:117db924cf7c | 1708 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1709 | } |
wolfSSL | 15:117db924cf7c | 1710 | |
wolfSSL | 15:117db924cf7c | 1711 | /* sanity check on type of RSA operation */ |
wolfSSL | 15:117db924cf7c | 1712 | switch (type) { |
wolfSSL | 15:117db924cf7c | 1713 | case RSA_PUBLIC_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1714 | case RSA_PUBLIC_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1715 | case RSA_PRIVATE_ENCRYPT: |
wolfSSL | 15:117db924cf7c | 1716 | case RSA_PRIVATE_DECRYPT: |
wolfSSL | 15:117db924cf7c | 1717 | break; |
wolfSSL | 15:117db924cf7c | 1718 | default: |
wolfSSL | 15:117db924cf7c | 1719 | WOLFSSL_MSG("Bad RSA type"); |
wolfSSL | 15:117db924cf7c | 1720 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1721 | } |
wolfSSL | 15:117db924cf7c | 1722 | |
wolfSSL | 15:117db924cf7c | 1723 | if ((ret = wc_RsaEncryptSize(key)) < 0) { |
wolfSSL | 15:117db924cf7c | 1724 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1725 | } |
wolfSSL | 15:117db924cf7c | 1726 | |
wolfSSL | 15:117db924cf7c | 1727 | if (inLen != (word32)ret) { |
wolfSSL | 15:117db924cf7c | 1728 | WOLFSSL_MSG("Bad input length. Should be RSA key size"); |
wolfSSL | 15:117db924cf7c | 1729 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1730 | } |
wolfSSL | 15:117db924cf7c | 1731 | |
wolfSSL | 15:117db924cf7c | 1732 | if (out == NULL) { |
wolfSSL | 15:117db924cf7c | 1733 | *outSz = inLen; |
wolfSSL | 15:117db924cf7c | 1734 | return LENGTH_ONLY_E; |
wolfSSL | 15:117db924cf7c | 1735 | } |
wolfSSL | 15:117db924cf7c | 1736 | |
wolfSSL | 15:117db924cf7c | 1737 | switch (key->state) { |
wolfSSL | 15:117db924cf7c | 1738 | case RSA_STATE_NONE: |
wolfSSL | 15:117db924cf7c | 1739 | case RSA_STATE_ENCRYPT_PAD: |
wolfSSL | 15:117db924cf7c | 1740 | case RSA_STATE_ENCRYPT_EXPTMOD: |
wolfSSL | 15:117db924cf7c | 1741 | case RSA_STATE_DECRYPT_EXPTMOD: |
wolfSSL | 15:117db924cf7c | 1742 | case RSA_STATE_DECRYPT_UNPAD: |
wolfSSL | 15:117db924cf7c | 1743 | key->state = (type == RSA_PRIVATE_ENCRYPT || |
wolfSSL | 15:117db924cf7c | 1744 | type == RSA_PUBLIC_ENCRYPT) ? RSA_STATE_ENCRYPT_EXPTMOD: |
wolfSSL | 15:117db924cf7c | 1745 | RSA_STATE_DECRYPT_EXPTMOD; |
wolfSSL | 15:117db924cf7c | 1746 | |
wolfSSL | 15:117db924cf7c | 1747 | key->dataLen = *outSz; |
wolfSSL | 15:117db924cf7c | 1748 | |
wolfSSL | 15:117db924cf7c | 1749 | ret = wc_RsaFunction(in, inLen, out, &key->dataLen, type, key, rng); |
wolfSSL | 15:117db924cf7c | 1750 | if (ret >= 0 || ret == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 1751 | key->state = (type == RSA_PRIVATE_ENCRYPT || |
wolfSSL | 15:117db924cf7c | 1752 | type == RSA_PUBLIC_ENCRYPT) ? RSA_STATE_ENCRYPT_RES: |
wolfSSL | 15:117db924cf7c | 1753 | RSA_STATE_DECRYPT_RES; |
wolfSSL | 15:117db924cf7c | 1754 | } |
wolfSSL | 15:117db924cf7c | 1755 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 1756 | break; |
wolfSSL | 15:117db924cf7c | 1757 | } |
wolfSSL | 15:117db924cf7c | 1758 | |
wolfSSL | 15:117db924cf7c | 1759 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 1760 | |
wolfSSL | 15:117db924cf7c | 1761 | case RSA_STATE_ENCRYPT_RES: |
wolfSSL | 15:117db924cf7c | 1762 | case RSA_STATE_DECRYPT_RES: |
wolfSSL | 15:117db924cf7c | 1763 | ret = key->dataLen; |
wolfSSL | 15:117db924cf7c | 1764 | break; |
wolfSSL | 15:117db924cf7c | 1765 | |
wolfSSL | 15:117db924cf7c | 1766 | default: |
wolfSSL | 15:117db924cf7c | 1767 | ret = BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 1768 | } |
wolfSSL | 15:117db924cf7c | 1769 | |
wolfSSL | 15:117db924cf7c | 1770 | /* if async pending then skip cleanup*/ |
wolfSSL | 15:117db924cf7c | 1771 | if (ret == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 1772 | return ret; |
wolfSSL | 15:117db924cf7c | 1773 | } |
wolfSSL | 15:117db924cf7c | 1774 | |
wolfSSL | 15:117db924cf7c | 1775 | key->state = RSA_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 1776 | wc_RsaCleanup(key); |
wolfSSL | 15:117db924cf7c | 1777 | |
wolfSSL | 15:117db924cf7c | 1778 | return ret; |
wolfSSL | 15:117db924cf7c | 1779 | } |
wolfSSL | 15:117db924cf7c | 1780 | #endif /* WC_RSA_DIRECT || WC_RSA_NO_PADDING */ |
wolfSSL | 15:117db924cf7c | 1781 | |
wolfSSL | 15:117db924cf7c | 1782 | |
wolfSSL | 15:117db924cf7c | 1783 | int wc_RsaFunction(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 1784 | word32* outLen, int type, RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 1785 | { |
wolfSSL | 15:117db924cf7c | 1786 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 1787 | |
wolfSSL | 15:117db924cf7c | 1788 | if (key == NULL || in == NULL || inLen == 0 || out == NULL || |
wolfSSL | 15:117db924cf7c | 1789 | outLen == NULL || *outLen == 0 || type == RSA_TYPE_UNKNOWN) { |
wolfSSL | 15:117db924cf7c | 1790 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1791 | } |
wolfSSL | 15:117db924cf7c | 1792 | |
wolfSSL | 15:117db924cf7c | 1793 | #ifdef WOLF_CRYPTO_DEV |
wolfSSL | 15:117db924cf7c | 1794 | if (key->devId != INVALID_DEVID) { |
wolfSSL | 15:117db924cf7c | 1795 | ret = wc_CryptoDev_Rsa(in, inLen, out, outLen, type, key, rng); |
wolfSSL | 15:117db924cf7c | 1796 | if (ret != NOT_COMPILED_IN) |
wolfSSL | 15:117db924cf7c | 1797 | return ret; |
wolfSSL | 15:117db924cf7c | 1798 | ret = 0; /* reset error code and try using software */ |
wolfSSL | 15:117db924cf7c | 1799 | } |
wolfSSL | 15:117db924cf7c | 1800 | #endif |
wolfSSL | 15:117db924cf7c | 1801 | |
wolfSSL | 15:117db924cf7c | 1802 | #ifndef NO_RSA_BOUNDS_CHECK |
wolfSSL | 15:117db924cf7c | 1803 | if (type == RSA_PRIVATE_DECRYPT && |
wolfSSL | 15:117db924cf7c | 1804 | key->state == RSA_STATE_DECRYPT_EXPTMOD) { |
wolfSSL | 15:117db924cf7c | 1805 | |
wolfSSL | 15:117db924cf7c | 1806 | /* Check that 1 < in < n-1. (Requirement of 800-56B.) */ |
wolfSSL | 15:117db924cf7c | 1807 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1808 | mp_int* c = NULL; |
wolfSSL | 15:117db924cf7c | 1809 | #else |
wolfSSL | 15:117db924cf7c | 1810 | mp_int c[1]; |
wolfSSL | 15:117db924cf7c | 1811 | #endif |
wolfSSL | 15:117db924cf7c | 1812 | |
wolfSSL | 15:117db924cf7c | 1813 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1814 | c = (mp_int*)XMALLOC(sizeof(mp_int), key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1815 | if (c == NULL) |
wolfSSL | 15:117db924cf7c | 1816 | ret = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1817 | #endif |
wolfSSL | 15:117db924cf7c | 1818 | |
wolfSSL | 15:117db924cf7c | 1819 | if (mp_init(c) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1820 | ret = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 1821 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1822 | if (mp_read_unsigned_bin(c, in, inLen) != 0) |
wolfSSL | 15:117db924cf7c | 1823 | ret = MP_READ_E; |
wolfSSL | 15:117db924cf7c | 1824 | } |
wolfSSL | 15:117db924cf7c | 1825 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1826 | /* check c > 1 */ |
wolfSSL | 15:117db924cf7c | 1827 | if (mp_cmp_d(c, 1) != MP_GT) |
wolfSSL | 15:117db924cf7c | 1828 | ret = RSA_OUT_OF_RANGE_E; |
wolfSSL | 15:117db924cf7c | 1829 | } |
wolfSSL | 15:117db924cf7c | 1830 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1831 | /* add c+1 */ |
wolfSSL | 15:117db924cf7c | 1832 | if (mp_add_d(c, 1, c) != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 1833 | ret = MP_ADD_E; |
wolfSSL | 15:117db924cf7c | 1834 | } |
wolfSSL | 15:117db924cf7c | 1835 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 1836 | /* check c+1 < n */ |
wolfSSL | 15:117db924cf7c | 1837 | if (mp_cmp(c, &key->n) != MP_LT) |
wolfSSL | 15:117db924cf7c | 1838 | ret = RSA_OUT_OF_RANGE_E; |
wolfSSL | 15:117db924cf7c | 1839 | } |
wolfSSL | 15:117db924cf7c | 1840 | mp_clear(c); |
wolfSSL | 15:117db924cf7c | 1841 | |
wolfSSL | 15:117db924cf7c | 1842 | #ifdef WOLFSSL_SMALL_STACK |
wolfSSL | 15:117db924cf7c | 1843 | XFREE(c, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 1844 | #endif |
wolfSSL | 15:117db924cf7c | 1845 | |
wolfSSL | 15:117db924cf7c | 1846 | if (ret != 0) |
wolfSSL | 15:117db924cf7c | 1847 | return ret; |
wolfSSL | 15:117db924cf7c | 1848 | } |
wolfSSL | 15:117db924cf7c | 1849 | #endif /* NO_RSA_BOUNDS_CHECK */ |
wolfSSL | 15:117db924cf7c | 1850 | |
wolfSSL | 15:117db924cf7c | 1851 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) |
wolfSSL | 15:117db924cf7c | 1852 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && |
wolfSSL | 15:117db924cf7c | 1853 | key->n.raw.len > 0) { |
wolfSSL | 15:117db924cf7c | 1854 | ret = wc_RsaFunctionAsync(in, inLen, out, outLen, type, key, rng); |
wolfSSL | 15:117db924cf7c | 1855 | } |
wolfSSL | 15:117db924cf7c | 1856 | else |
wolfSSL | 15:117db924cf7c | 1857 | #endif |
wolfSSL | 15:117db924cf7c | 1858 | { |
wolfSSL | 15:117db924cf7c | 1859 | ret = wc_RsaFunctionSync(in, inLen, out, outLen, type, key, rng); |
wolfSSL | 15:117db924cf7c | 1860 | } |
wolfSSL | 15:117db924cf7c | 1861 | |
wolfSSL | 15:117db924cf7c | 1862 | /* handle error */ |
wolfSSL | 15:117db924cf7c | 1863 | if (ret < 0 && ret != WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 1864 | if (ret == MP_EXPTMOD_E) { |
wolfSSL | 15:117db924cf7c | 1865 | /* This can happen due to incorrectly set FP_MAX_BITS or missing XREALLOC */ |
wolfSSL | 15:117db924cf7c | 1866 | WOLFSSL_MSG("RSA_FUNCTION MP_EXPTMOD_E: memory/config problem"); |
wolfSSL | 15:117db924cf7c | 1867 | } |
wolfSSL | 15:117db924cf7c | 1868 | |
wolfSSL | 15:117db924cf7c | 1869 | key->state = RSA_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 1870 | wc_RsaCleanup(key); |
wolfSSL | 15:117db924cf7c | 1871 | } |
wolfSSL | 15:117db924cf7c | 1872 | |
wolfSSL | 15:117db924cf7c | 1873 | return ret; |
wolfSSL | 15:117db924cf7c | 1874 | } |
wolfSSL | 15:117db924cf7c | 1875 | |
wolfSSL | 15:117db924cf7c | 1876 | |
wolfSSL | 15:117db924cf7c | 1877 | /* Internal Wrappers */ |
wolfSSL | 15:117db924cf7c | 1878 | /* Gives the option of choosing padding type |
wolfSSL | 15:117db924cf7c | 1879 | in : input to be encrypted |
wolfSSL | 15:117db924cf7c | 1880 | inLen: length of input buffer |
wolfSSL | 15:117db924cf7c | 1881 | out: encrypted output |
wolfSSL | 15:117db924cf7c | 1882 | outLen: length of encrypted output buffer |
wolfSSL | 15:117db924cf7c | 1883 | key : wolfSSL initialized RSA key struct |
wolfSSL | 15:117db924cf7c | 1884 | rng : wolfSSL initialized random number struct |
wolfSSL | 15:117db924cf7c | 1885 | rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT, |
wolfSSL | 15:117db924cf7c | 1886 | RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT |
wolfSSL | 15:117db924cf7c | 1887 | pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2 |
wolfSSL | 15:117db924cf7c | 1888 | pad_type : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD, |
wolfSSL | 15:117db924cf7c | 1889 | WC_RSA_NO_PAD or WC_RSA_PSS_PAD |
wolfSSL | 15:117db924cf7c | 1890 | hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h |
wolfSSL | 15:117db924cf7c | 1891 | mgf : type of mask generation function to use |
wolfSSL | 15:117db924cf7c | 1892 | label : optional label |
wolfSSL | 15:117db924cf7c | 1893 | labelSz : size of optional label buffer |
wolfSSL | 15:117db924cf7c | 1894 | saltLen : Length of salt used in PSS |
wolfSSL | 15:117db924cf7c | 1895 | rng : random number generator */ |
wolfSSL | 15:117db924cf7c | 1896 | static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 1897 | word32 outLen, RsaKey* key, int rsa_type, |
wolfSSL | 15:117db924cf7c | 1898 | byte pad_value, int pad_type, |
wolfSSL | 15:117db924cf7c | 1899 | enum wc_HashType hash, int mgf, |
wolfSSL | 15:117db924cf7c | 1900 | byte* label, word32 labelSz, int saltLen, |
wolfSSL | 15:117db924cf7c | 1901 | WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 1902 | { |
wolfSSL | 15:117db924cf7c | 1903 | int ret, sz; |
wolfSSL | 15:117db924cf7c | 1904 | |
wolfSSL | 15:117db924cf7c | 1905 | if (in == NULL || inLen == 0 || out == NULL || key == NULL) { |
wolfSSL | 15:117db924cf7c | 1906 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 1907 | } |
wolfSSL | 15:117db924cf7c | 1908 | |
wolfSSL | 15:117db924cf7c | 1909 | sz = wc_RsaEncryptSize(key); |
wolfSSL | 15:117db924cf7c | 1910 | if (sz > (int)outLen) { |
wolfSSL | 15:117db924cf7c | 1911 | return RSA_BUFFER_E; |
wolfSSL | 15:117db924cf7c | 1912 | } |
wolfSSL | 15:117db924cf7c | 1913 | |
wolfSSL | 15:117db924cf7c | 1914 | if (sz < RSA_MIN_PAD_SZ) { |
wolfSSL | 15:117db924cf7c | 1915 | return WC_KEY_SIZE_E; |
wolfSSL | 15:117db924cf7c | 1916 | } |
wolfSSL | 15:117db924cf7c | 1917 | |
wolfSSL | 15:117db924cf7c | 1918 | if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) { |
wolfSSL | 15:117db924cf7c | 1919 | #ifdef WC_RSA_NO_PADDING |
wolfSSL | 15:117db924cf7c | 1920 | /* In the case that no padding is used the input length can and should |
wolfSSL | 15:117db924cf7c | 1921 | * be the same size as the RSA key. */ |
wolfSSL | 15:117db924cf7c | 1922 | if (pad_type != WC_RSA_NO_PAD) |
wolfSSL | 15:117db924cf7c | 1923 | #endif |
wolfSSL | 15:117db924cf7c | 1924 | return RSA_BUFFER_E; |
wolfSSL | 15:117db924cf7c | 1925 | } |
wolfSSL | 15:117db924cf7c | 1926 | |
wolfSSL | 15:117db924cf7c | 1927 | switch (key->state) { |
wolfSSL | 15:117db924cf7c | 1928 | case RSA_STATE_NONE: |
wolfSSL | 15:117db924cf7c | 1929 | case RSA_STATE_ENCRYPT_PAD: |
wolfSSL | 15:117db924cf7c | 1930 | key->state = RSA_STATE_ENCRYPT_PAD; |
wolfSSL | 15:117db924cf7c | 1931 | |
wolfSSL | 15:117db924cf7c | 1932 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \ |
wolfSSL | 15:117db924cf7c | 1933 | defined(HAVE_CAVIUM) |
wolfSSL | 15:117db924cf7c | 1934 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && |
wolfSSL | 15:117db924cf7c | 1935 | pad_type != WC_RSA_PSS_PAD && key->n.raw.buf) { |
wolfSSL | 15:117db924cf7c | 1936 | /* Async operations that include padding */ |
wolfSSL | 15:117db924cf7c | 1937 | if (rsa_type == RSA_PUBLIC_ENCRYPT && |
wolfSSL | 15:117db924cf7c | 1938 | pad_value == RSA_BLOCK_TYPE_2) { |
wolfSSL | 15:117db924cf7c | 1939 | key->state = RSA_STATE_ENCRYPT_RES; |
wolfSSL | 15:117db924cf7c | 1940 | key->dataLen = key->n.raw.len; |
wolfSSL | 15:117db924cf7c | 1941 | return NitroxRsaPublicEncrypt(in, inLen, out, outLen, key); |
wolfSSL | 15:117db924cf7c | 1942 | } |
wolfSSL | 15:117db924cf7c | 1943 | else if (rsa_type == RSA_PRIVATE_ENCRYPT && |
wolfSSL | 15:117db924cf7c | 1944 | pad_value == RSA_BLOCK_TYPE_1) { |
wolfSSL | 15:117db924cf7c | 1945 | key->state = RSA_STATE_ENCRYPT_RES; |
wolfSSL | 15:117db924cf7c | 1946 | key->dataLen = key->n.raw.len; |
wolfSSL | 15:117db924cf7c | 1947 | return NitroxRsaSSL_Sign(in, inLen, out, outLen, key); |
wolfSSL | 15:117db924cf7c | 1948 | } |
wolfSSL | 15:117db924cf7c | 1949 | } |
wolfSSL | 15:117db924cf7c | 1950 | #endif |
wolfSSL | 15:117db924cf7c | 1951 | |
wolfSSL | 15:117db924cf7c | 1952 | ret = wc_RsaPad_ex(in, inLen, out, sz, pad_value, rng, pad_type, hash, |
wolfSSL | 15:117db924cf7c | 1953 | mgf, label, labelSz, saltLen, mp_count_bits(&key->n), |
wolfSSL | 15:117db924cf7c | 1954 | key->heap); |
wolfSSL | 15:117db924cf7c | 1955 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 1956 | break; |
wolfSSL | 15:117db924cf7c | 1957 | } |
wolfSSL | 15:117db924cf7c | 1958 | |
wolfSSL | 15:117db924cf7c | 1959 | key->state = RSA_STATE_ENCRYPT_EXPTMOD; |
wolfSSL | 15:117db924cf7c | 1960 | |
wolfSSL | 15:117db924cf7c | 1961 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 1962 | |
wolfSSL | 15:117db924cf7c | 1963 | case RSA_STATE_ENCRYPT_EXPTMOD: |
wolfSSL | 15:117db924cf7c | 1964 | |
wolfSSL | 15:117db924cf7c | 1965 | key->dataLen = outLen; |
wolfSSL | 15:117db924cf7c | 1966 | ret = wc_RsaFunction(out, sz, out, &key->dataLen, rsa_type, key, rng); |
wolfSSL | 15:117db924cf7c | 1967 | |
wolfSSL | 15:117db924cf7c | 1968 | if (ret >= 0 || ret == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 1969 | key->state = RSA_STATE_ENCRYPT_RES; |
wolfSSL | 15:117db924cf7c | 1970 | } |
wolfSSL | 15:117db924cf7c | 1971 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 1972 | break; |
wolfSSL | 15:117db924cf7c | 1973 | } |
wolfSSL | 15:117db924cf7c | 1974 | |
wolfSSL | 15:117db924cf7c | 1975 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 1976 | |
wolfSSL | 15:117db924cf7c | 1977 | case RSA_STATE_ENCRYPT_RES: |
wolfSSL | 15:117db924cf7c | 1978 | ret = key->dataLen; |
wolfSSL | 15:117db924cf7c | 1979 | break; |
wolfSSL | 15:117db924cf7c | 1980 | |
wolfSSL | 15:117db924cf7c | 1981 | default: |
wolfSSL | 15:117db924cf7c | 1982 | ret = BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 1983 | break; |
wolfSSL | 15:117db924cf7c | 1984 | } |
wolfSSL | 15:117db924cf7c | 1985 | |
wolfSSL | 15:117db924cf7c | 1986 | /* if async pending then return and skip done cleanup below */ |
wolfSSL | 15:117db924cf7c | 1987 | if (ret == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 1988 | return ret; |
wolfSSL | 15:117db924cf7c | 1989 | } |
wolfSSL | 15:117db924cf7c | 1990 | |
wolfSSL | 15:117db924cf7c | 1991 | key->state = RSA_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 1992 | wc_RsaCleanup(key); |
wolfSSL | 15:117db924cf7c | 1993 | |
wolfSSL | 15:117db924cf7c | 1994 | return ret; |
wolfSSL | 15:117db924cf7c | 1995 | } |
wolfSSL | 15:117db924cf7c | 1996 | |
wolfSSL | 15:117db924cf7c | 1997 | /* Gives the option of choosing padding type |
wolfSSL | 15:117db924cf7c | 1998 | in : input to be decrypted |
wolfSSL | 15:117db924cf7c | 1999 | inLen: length of input buffer |
wolfSSL | 15:117db924cf7c | 2000 | out: decrypted message |
wolfSSL | 15:117db924cf7c | 2001 | outLen: length of decrypted message in bytes |
wolfSSL | 15:117db924cf7c | 2002 | outPtr: optional inline output pointer (if provided doing inline) |
wolfSSL | 15:117db924cf7c | 2003 | key : wolfSSL initialized RSA key struct |
wolfSSL | 15:117db924cf7c | 2004 | rsa_type : type of RSA: RSA_PUBLIC_ENCRYPT, RSA_PUBLIC_DECRYPT, |
wolfSSL | 15:117db924cf7c | 2005 | RSA_PRIVATE_ENCRYPT or RSA_PRIVATE_DECRYPT |
wolfSSL | 15:117db924cf7c | 2006 | pad_value: RSA_BLOCK_TYPE_1 or RSA_BLOCK_TYPE_2 |
wolfSSL | 15:117db924cf7c | 2007 | pad_type : type of padding: WC_RSA_PKCSV15_PAD, WC_RSA_OAEP_PAD, |
wolfSSL | 15:117db924cf7c | 2008 | WC_RSA_NO_PAD, WC_RSA_PSS_PAD |
wolfSSL | 15:117db924cf7c | 2009 | hash : type of hash algorithm to use found in wolfssl/wolfcrypt/hash.h |
wolfSSL | 15:117db924cf7c | 2010 | mgf : type of mask generation function to use |
wolfSSL | 15:117db924cf7c | 2011 | label : optional label |
wolfSSL | 15:117db924cf7c | 2012 | labelSz : size of optional label buffer |
wolfSSL | 15:117db924cf7c | 2013 | saltLen : Length of salt used in PSS |
wolfSSL | 15:117db924cf7c | 2014 | rng : random number generator */ |
wolfSSL | 15:117db924cf7c | 2015 | static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 2016 | word32 outLen, byte** outPtr, RsaKey* key, |
wolfSSL | 15:117db924cf7c | 2017 | int rsa_type, byte pad_value, int pad_type, |
wolfSSL | 15:117db924cf7c | 2018 | enum wc_HashType hash, int mgf, |
wolfSSL | 15:117db924cf7c | 2019 | byte* label, word32 labelSz, int saltLen, |
wolfSSL | 15:117db924cf7c | 2020 | WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 2021 | { |
wolfSSL | 15:117db924cf7c | 2022 | int ret = RSA_WRONG_TYPE_E; |
wolfSSL | 15:117db924cf7c | 2023 | |
wolfSSL | 15:117db924cf7c | 2024 | if (in == NULL || inLen == 0 || out == NULL || key == NULL) { |
wolfSSL | 15:117db924cf7c | 2025 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2026 | } |
wolfSSL | 15:117db924cf7c | 2027 | |
wolfSSL | 15:117db924cf7c | 2028 | switch (key->state) { |
wolfSSL | 15:117db924cf7c | 2029 | case RSA_STATE_NONE: |
wolfSSL | 15:117db924cf7c | 2030 | case RSA_STATE_DECRYPT_EXPTMOD: |
wolfSSL | 15:117db924cf7c | 2031 | key->state = RSA_STATE_DECRYPT_EXPTMOD; |
wolfSSL | 15:117db924cf7c | 2032 | key->dataLen = inLen; |
wolfSSL | 15:117db924cf7c | 2033 | |
wolfSSL | 15:117db924cf7c | 2034 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \ |
wolfSSL | 15:117db924cf7c | 2035 | defined(HAVE_CAVIUM) |
wolfSSL | 15:117db924cf7c | 2036 | /* Async operations that include padding */ |
wolfSSL | 15:117db924cf7c | 2037 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && |
wolfSSL | 15:117db924cf7c | 2038 | pad_type != WC_RSA_PSS_PAD) { |
wolfSSL | 15:117db924cf7c | 2039 | if (rsa_type == RSA_PRIVATE_DECRYPT && |
wolfSSL | 15:117db924cf7c | 2040 | pad_value == RSA_BLOCK_TYPE_2) { |
wolfSSL | 15:117db924cf7c | 2041 | key->state = RSA_STATE_DECRYPT_RES; |
wolfSSL | 15:117db924cf7c | 2042 | key->data = NULL; |
wolfSSL | 15:117db924cf7c | 2043 | return NitroxRsaPrivateDecrypt(in, inLen, out, &key->dataLen, |
wolfSSL | 15:117db924cf7c | 2044 | key); |
wolfSSL | 15:117db924cf7c | 2045 | } |
wolfSSL | 15:117db924cf7c | 2046 | else if (rsa_type == RSA_PUBLIC_DECRYPT && |
wolfSSL | 15:117db924cf7c | 2047 | pad_value == RSA_BLOCK_TYPE_1) { |
wolfSSL | 15:117db924cf7c | 2048 | key->state = RSA_STATE_DECRYPT_RES; |
wolfSSL | 15:117db924cf7c | 2049 | key->data = NULL; |
wolfSSL | 15:117db924cf7c | 2050 | return NitroxRsaSSL_Verify(in, inLen, out, &key->dataLen, key); |
wolfSSL | 15:117db924cf7c | 2051 | } |
wolfSSL | 15:117db924cf7c | 2052 | } |
wolfSSL | 15:117db924cf7c | 2053 | #endif |
wolfSSL | 15:117db924cf7c | 2054 | |
wolfSSL | 15:117db924cf7c | 2055 | /* verify the tmp ptr is NULL, otherwise indicates bad state */ |
wolfSSL | 15:117db924cf7c | 2056 | if (key->data != NULL) { |
wolfSSL | 15:117db924cf7c | 2057 | ret = BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 2058 | break; |
wolfSSL | 15:117db924cf7c | 2059 | } |
wolfSSL | 15:117db924cf7c | 2060 | |
wolfSSL | 15:117db924cf7c | 2061 | /* if not doing this inline then allocate a buffer for it */ |
wolfSSL | 15:117db924cf7c | 2062 | if (outPtr == NULL) { |
wolfSSL | 15:117db924cf7c | 2063 | key->data = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_WOLF_BIGINT); |
wolfSSL | 15:117db924cf7c | 2064 | key->dataIsAlloc = 1; |
wolfSSL | 15:117db924cf7c | 2065 | if (key->data == NULL) { |
wolfSSL | 15:117db924cf7c | 2066 | ret = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 2067 | break; |
wolfSSL | 15:117db924cf7c | 2068 | } |
wolfSSL | 15:117db924cf7c | 2069 | XMEMCPY(key->data, in, inLen); |
wolfSSL | 15:117db924cf7c | 2070 | } |
wolfSSL | 15:117db924cf7c | 2071 | else { |
wolfSSL | 15:117db924cf7c | 2072 | key->data = out; |
wolfSSL | 15:117db924cf7c | 2073 | } |
wolfSSL | 15:117db924cf7c | 2074 | ret = wc_RsaFunction(key->data, inLen, key->data, &key->dataLen, rsa_type, |
wolfSSL | 15:117db924cf7c | 2075 | key, rng); |
wolfSSL | 15:117db924cf7c | 2076 | |
wolfSSL | 15:117db924cf7c | 2077 | if (ret >= 0 || ret == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 2078 | key->state = RSA_STATE_DECRYPT_UNPAD; |
wolfSSL | 15:117db924cf7c | 2079 | } |
wolfSSL | 15:117db924cf7c | 2080 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 2081 | break; |
wolfSSL | 15:117db924cf7c | 2082 | } |
wolfSSL | 15:117db924cf7c | 2083 | |
wolfSSL | 15:117db924cf7c | 2084 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 2085 | |
wolfSSL | 15:117db924cf7c | 2086 | case RSA_STATE_DECRYPT_UNPAD: |
wolfSSL | 15:117db924cf7c | 2087 | { |
wolfSSL | 15:117db924cf7c | 2088 | byte* pad = NULL; |
wolfSSL | 15:117db924cf7c | 2089 | ret = wc_RsaUnPad_ex(key->data, key->dataLen, &pad, pad_value, pad_type, |
wolfSSL | 15:117db924cf7c | 2090 | hash, mgf, label, labelSz, saltLen, |
wolfSSL | 15:117db924cf7c | 2091 | mp_count_bits(&key->n), key->heap); |
wolfSSL | 15:117db924cf7c | 2092 | if (ret > 0 && ret <= (int)outLen && pad != NULL) { |
wolfSSL | 15:117db924cf7c | 2093 | /* only copy output if not inline */ |
wolfSSL | 15:117db924cf7c | 2094 | if (outPtr == NULL) { |
wolfSSL | 15:117db924cf7c | 2095 | XMEMCPY(out, pad, ret); |
wolfSSL | 15:117db924cf7c | 2096 | } |
wolfSSL | 15:117db924cf7c | 2097 | else { |
wolfSSL | 15:117db924cf7c | 2098 | *outPtr = pad; |
wolfSSL | 15:117db924cf7c | 2099 | } |
wolfSSL | 15:117db924cf7c | 2100 | } |
wolfSSL | 15:117db924cf7c | 2101 | else if (ret >= 0) { |
wolfSSL | 15:117db924cf7c | 2102 | ret = RSA_BUFFER_E; |
wolfSSL | 15:117db924cf7c | 2103 | } |
wolfSSL | 15:117db924cf7c | 2104 | if (ret < 0) { |
wolfSSL | 15:117db924cf7c | 2105 | break; |
wolfSSL | 15:117db924cf7c | 2106 | } |
wolfSSL | 15:117db924cf7c | 2107 | |
wolfSSL | 15:117db924cf7c | 2108 | key->state = RSA_STATE_DECRYPT_RES; |
wolfSSL | 15:117db924cf7c | 2109 | |
wolfSSL | 15:117db924cf7c | 2110 | FALL_THROUGH; |
wolfSSL | 15:117db924cf7c | 2111 | } |
wolfSSL | 15:117db924cf7c | 2112 | case RSA_STATE_DECRYPT_RES: |
wolfSSL | 15:117db924cf7c | 2113 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) && \ |
wolfSSL | 15:117db924cf7c | 2114 | defined(HAVE_CAVIUM) |
wolfSSL | 15:117db924cf7c | 2115 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA && |
wolfSSL | 15:117db924cf7c | 2116 | pad_type != WC_RSA_PSS_PAD) { |
wolfSSL | 15:117db924cf7c | 2117 | /* convert result */ |
wolfSSL | 15:117db924cf7c | 2118 | byte* dataLen = (byte*)&key->dataLen; |
wolfSSL | 15:117db924cf7c | 2119 | ret = (dataLen[0] << 8) | (dataLen[1]); |
wolfSSL | 15:117db924cf7c | 2120 | |
wolfSSL | 15:117db924cf7c | 2121 | if (outPtr) |
wolfSSL | 15:117db924cf7c | 2122 | *outPtr = in; |
wolfSSL | 15:117db924cf7c | 2123 | } |
wolfSSL | 15:117db924cf7c | 2124 | #endif |
wolfSSL | 15:117db924cf7c | 2125 | break; |
wolfSSL | 15:117db924cf7c | 2126 | |
wolfSSL | 15:117db924cf7c | 2127 | default: |
wolfSSL | 15:117db924cf7c | 2128 | ret = BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 2129 | break; |
wolfSSL | 15:117db924cf7c | 2130 | } |
wolfSSL | 15:117db924cf7c | 2131 | |
wolfSSL | 15:117db924cf7c | 2132 | /* if async pending then return and skip done cleanup below */ |
wolfSSL | 15:117db924cf7c | 2133 | if (ret == WC_PENDING_E) { |
wolfSSL | 15:117db924cf7c | 2134 | return ret; |
wolfSSL | 15:117db924cf7c | 2135 | } |
wolfSSL | 15:117db924cf7c | 2136 | |
wolfSSL | 15:117db924cf7c | 2137 | key->state = RSA_STATE_NONE; |
wolfSSL | 15:117db924cf7c | 2138 | wc_RsaCleanup(key); |
wolfSSL | 15:117db924cf7c | 2139 | |
wolfSSL | 15:117db924cf7c | 2140 | return ret; |
wolfSSL | 15:117db924cf7c | 2141 | } |
wolfSSL | 15:117db924cf7c | 2142 | |
wolfSSL | 15:117db924cf7c | 2143 | |
wolfSSL | 15:117db924cf7c | 2144 | /* Public RSA Functions */ |
wolfSSL | 15:117db924cf7c | 2145 | int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, |
wolfSSL | 15:117db924cf7c | 2146 | RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 2147 | { |
wolfSSL | 15:117db924cf7c | 2148 | return RsaPublicEncryptEx(in, inLen, out, outLen, key, |
wolfSSL | 15:117db924cf7c | 2149 | RSA_PUBLIC_ENCRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, |
wolfSSL | 15:117db924cf7c | 2150 | WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng); |
wolfSSL | 15:117db924cf7c | 2151 | } |
wolfSSL | 15:117db924cf7c | 2152 | |
wolfSSL | 15:117db924cf7c | 2153 | |
wolfSSL | 15:117db924cf7c | 2154 | #if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING) |
wolfSSL | 15:117db924cf7c | 2155 | int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 2156 | word32 outLen, RsaKey* key, WC_RNG* rng, int type, |
wolfSSL | 15:117db924cf7c | 2157 | enum wc_HashType hash, int mgf, byte* label, |
wolfSSL | 15:117db924cf7c | 2158 | word32 labelSz) |
wolfSSL | 15:117db924cf7c | 2159 | { |
wolfSSL | 15:117db924cf7c | 2160 | return RsaPublicEncryptEx(in, inLen, out, outLen, key, RSA_PUBLIC_ENCRYPT, |
wolfSSL | 15:117db924cf7c | 2161 | RSA_BLOCK_TYPE_2, type, hash, mgf, label, labelSz, 0, rng); |
wolfSSL | 15:117db924cf7c | 2162 | } |
wolfSSL | 15:117db924cf7c | 2163 | #endif /* WC_NO_RSA_OAEP */ |
wolfSSL | 15:117db924cf7c | 2164 | |
wolfSSL | 15:117db924cf7c | 2165 | |
wolfSSL | 15:117db924cf7c | 2166 | int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2167 | { |
wolfSSL | 15:117db924cf7c | 2168 | WC_RNG* rng = NULL; |
wolfSSL | 15:117db924cf7c | 2169 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 2170 | rng = key->rng; |
wolfSSL | 15:117db924cf7c | 2171 | #endif |
wolfSSL | 15:117db924cf7c | 2172 | return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, |
wolfSSL | 15:117db924cf7c | 2173 | RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, |
wolfSSL | 15:117db924cf7c | 2174 | WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng); |
wolfSSL | 15:117db924cf7c | 2175 | } |
wolfSSL | 15:117db924cf7c | 2176 | |
wolfSSL | 15:117db924cf7c | 2177 | |
wolfSSL | 15:117db924cf7c | 2178 | #ifndef WC_NO_RSA_OAEP |
wolfSSL | 15:117db924cf7c | 2179 | int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out, |
wolfSSL | 15:117db924cf7c | 2180 | RsaKey* key, int type, enum wc_HashType hash, |
wolfSSL | 15:117db924cf7c | 2181 | int mgf, byte* label, word32 labelSz) |
wolfSSL | 15:117db924cf7c | 2182 | { |
wolfSSL | 15:117db924cf7c | 2183 | WC_RNG* rng = NULL; |
wolfSSL | 15:117db924cf7c | 2184 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 2185 | rng = key->rng; |
wolfSSL | 15:117db924cf7c | 2186 | #endif |
wolfSSL | 15:117db924cf7c | 2187 | return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, |
wolfSSL | 15:117db924cf7c | 2188 | RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, |
wolfSSL | 15:117db924cf7c | 2189 | mgf, label, labelSz, 0, rng); |
wolfSSL | 15:117db924cf7c | 2190 | } |
wolfSSL | 15:117db924cf7c | 2191 | #endif /* WC_NO_RSA_OAEP */ |
wolfSSL | 15:117db924cf7c | 2192 | |
wolfSSL | 15:117db924cf7c | 2193 | |
wolfSSL | 15:117db924cf7c | 2194 | int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 2195 | word32 outLen, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2196 | { |
wolfSSL | 15:117db924cf7c | 2197 | WC_RNG* rng = NULL; |
wolfSSL | 15:117db924cf7c | 2198 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 2199 | rng = key->rng; |
wolfSSL | 15:117db924cf7c | 2200 | #endif |
wolfSSL | 15:117db924cf7c | 2201 | return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, |
wolfSSL | 15:117db924cf7c | 2202 | RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, |
wolfSSL | 15:117db924cf7c | 2203 | WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng); |
wolfSSL | 15:117db924cf7c | 2204 | } |
wolfSSL | 15:117db924cf7c | 2205 | |
wolfSSL | 15:117db924cf7c | 2206 | #if !defined(WC_NO_RSA_OAEP) || defined(WC_RSA_NO_PADDING) |
wolfSSL | 15:117db924cf7c | 2207 | int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, |
wolfSSL | 15:117db924cf7c | 2208 | word32 outLen, RsaKey* key, int type, |
wolfSSL | 15:117db924cf7c | 2209 | enum wc_HashType hash, int mgf, byte* label, |
wolfSSL | 15:117db924cf7c | 2210 | word32 labelSz) |
wolfSSL | 15:117db924cf7c | 2211 | { |
wolfSSL | 15:117db924cf7c | 2212 | WC_RNG* rng = NULL; |
wolfSSL | 15:117db924cf7c | 2213 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 2214 | rng = key->rng; |
wolfSSL | 15:117db924cf7c | 2215 | #endif |
wolfSSL | 15:117db924cf7c | 2216 | return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, |
wolfSSL | 15:117db924cf7c | 2217 | RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label, |
wolfSSL | 15:117db924cf7c | 2218 | labelSz, 0, rng); |
wolfSSL | 15:117db924cf7c | 2219 | } |
wolfSSL | 15:117db924cf7c | 2220 | #endif /* WC_NO_RSA_OAEP || WC_RSA_NO_PADDING */ |
wolfSSL | 15:117db924cf7c | 2221 | |
wolfSSL | 15:117db924cf7c | 2222 | |
wolfSSL | 15:117db924cf7c | 2223 | int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2224 | { |
wolfSSL | 15:117db924cf7c | 2225 | WC_RNG* rng = NULL; |
wolfSSL | 15:117db924cf7c | 2226 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 2227 | rng = key->rng; |
wolfSSL | 15:117db924cf7c | 2228 | #endif |
wolfSSL | 15:117db924cf7c | 2229 | return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, |
wolfSSL | 15:117db924cf7c | 2230 | RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, |
wolfSSL | 15:117db924cf7c | 2231 | WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng); |
wolfSSL | 15:117db924cf7c | 2232 | } |
wolfSSL | 15:117db924cf7c | 2233 | |
wolfSSL | 15:117db924cf7c | 2234 | int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, |
wolfSSL | 15:117db924cf7c | 2235 | RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2236 | { |
wolfSSL | 15:117db924cf7c | 2237 | WC_RNG* rng; |
wolfSSL | 15:117db924cf7c | 2238 | |
wolfSSL | 15:117db924cf7c | 2239 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 2240 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2241 | } |
wolfSSL | 15:117db924cf7c | 2242 | |
wolfSSL | 15:117db924cf7c | 2243 | rng = NULL; |
wolfSSL | 15:117db924cf7c | 2244 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 2245 | rng = key->rng; |
wolfSSL | 15:117db924cf7c | 2246 | #endif |
wolfSSL | 15:117db924cf7c | 2247 | return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, |
wolfSSL | 15:117db924cf7c | 2248 | RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, |
wolfSSL | 15:117db924cf7c | 2249 | WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng); |
wolfSSL | 15:117db924cf7c | 2250 | } |
wolfSSL | 15:117db924cf7c | 2251 | |
wolfSSL | 15:117db924cf7c | 2252 | #ifdef WC_RSA_PSS |
wolfSSL | 15:117db924cf7c | 2253 | /* Verify the message signed with RSA-PSS. |
wolfSSL | 15:117db924cf7c | 2254 | * The input buffer is reused for the ouput buffer. |
wolfSSL | 15:117db924cf7c | 2255 | * Salt length is equal to hash length. |
wolfSSL | 15:117db924cf7c | 2256 | * |
wolfSSL | 15:117db924cf7c | 2257 | * in Buffer holding encrypted data. |
wolfSSL | 15:117db924cf7c | 2258 | * inLen Length of data in buffer. |
wolfSSL | 15:117db924cf7c | 2259 | * out Pointer to address containing the PSS data. |
wolfSSL | 15:117db924cf7c | 2260 | * hash Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2261 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 2262 | * key Public RSA key. |
wolfSSL | 15:117db924cf7c | 2263 | * returns the length of the PSS data on success and negative indicates failure. |
wolfSSL | 15:117db924cf7c | 2264 | */ |
wolfSSL | 15:117db924cf7c | 2265 | int wc_RsaPSS_VerifyInline(byte* in, word32 inLen, byte** out, |
wolfSSL | 15:117db924cf7c | 2266 | enum wc_HashType hash, int mgf, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2267 | { |
wolfSSL | 15:117db924cf7c | 2268 | return wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf, -1, key); |
wolfSSL | 15:117db924cf7c | 2269 | } |
wolfSSL | 15:117db924cf7c | 2270 | |
wolfSSL | 15:117db924cf7c | 2271 | /* Verify the message signed with RSA-PSS. |
wolfSSL | 15:117db924cf7c | 2272 | * The input buffer is reused for the ouput buffer. |
wolfSSL | 15:117db924cf7c | 2273 | * |
wolfSSL | 15:117db924cf7c | 2274 | * in Buffer holding encrypted data. |
wolfSSL | 15:117db924cf7c | 2275 | * inLen Length of data in buffer. |
wolfSSL | 15:117db924cf7c | 2276 | * out Pointer to address containing the PSS data. |
wolfSSL | 15:117db924cf7c | 2277 | * hash Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2278 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 2279 | * key Public RSA key. |
wolfSSL | 15:117db924cf7c | 2280 | * saltLen Length of salt used. -1 indicates salt length is the same as the |
wolfSSL | 15:117db924cf7c | 2281 | * hash length. |
wolfSSL | 15:117db924cf7c | 2282 | * returns the length of the PSS data on success and negative indicates failure. |
wolfSSL | 15:117db924cf7c | 2283 | */ |
wolfSSL | 15:117db924cf7c | 2284 | int wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out, |
wolfSSL | 15:117db924cf7c | 2285 | enum wc_HashType hash, int mgf, int saltLen, |
wolfSSL | 15:117db924cf7c | 2286 | RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2287 | { |
wolfSSL | 15:117db924cf7c | 2288 | WC_RNG* rng = NULL; |
wolfSSL | 15:117db924cf7c | 2289 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 2290 | rng = key->rng; |
wolfSSL | 15:117db924cf7c | 2291 | #endif |
wolfSSL | 15:117db924cf7c | 2292 | return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, |
wolfSSL | 15:117db924cf7c | 2293 | RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, |
wolfSSL | 15:117db924cf7c | 2294 | hash, mgf, NULL, 0, saltLen, rng); |
wolfSSL | 15:117db924cf7c | 2295 | } |
wolfSSL | 15:117db924cf7c | 2296 | |
wolfSSL | 15:117db924cf7c | 2297 | /* Verify the message signed with RSA-PSS. |
wolfSSL | 15:117db924cf7c | 2298 | * Salt length is equal to hash length. |
wolfSSL | 15:117db924cf7c | 2299 | * |
wolfSSL | 15:117db924cf7c | 2300 | * in Buffer holding encrypted data. |
wolfSSL | 15:117db924cf7c | 2301 | * inLen Length of data in buffer. |
wolfSSL | 15:117db924cf7c | 2302 | * out Pointer to address containing the PSS data. |
wolfSSL | 15:117db924cf7c | 2303 | * hash Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2304 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 2305 | * key Public RSA key. |
wolfSSL | 15:117db924cf7c | 2306 | * returns the length of the PSS data on success and negative indicates failure. |
wolfSSL | 15:117db924cf7c | 2307 | */ |
wolfSSL | 15:117db924cf7c | 2308 | int wc_RsaPSS_Verify(byte* in, word32 inLen, byte* out, word32 outLen, |
wolfSSL | 15:117db924cf7c | 2309 | enum wc_HashType hash, int mgf, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2310 | { |
wolfSSL | 15:117db924cf7c | 2311 | return wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash, mgf, -1, key); |
wolfSSL | 15:117db924cf7c | 2312 | } |
wolfSSL | 15:117db924cf7c | 2313 | |
wolfSSL | 15:117db924cf7c | 2314 | /* Verify the message signed with RSA-PSS. |
wolfSSL | 15:117db924cf7c | 2315 | * |
wolfSSL | 15:117db924cf7c | 2316 | * in Buffer holding encrypted data. |
wolfSSL | 15:117db924cf7c | 2317 | * inLen Length of data in buffer. |
wolfSSL | 15:117db924cf7c | 2318 | * out Pointer to address containing the PSS data. |
wolfSSL | 15:117db924cf7c | 2319 | * hash Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2320 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 2321 | * key Public RSA key. |
wolfSSL | 15:117db924cf7c | 2322 | * saltLen Length of salt used. -1 indicates salt length is the same as the |
wolfSSL | 15:117db924cf7c | 2323 | * hash length. |
wolfSSL | 15:117db924cf7c | 2324 | * returns the length of the PSS data on success and negative indicates failure. |
wolfSSL | 15:117db924cf7c | 2325 | */ |
wolfSSL | 15:117db924cf7c | 2326 | int wc_RsaPSS_Verify_ex(byte* in, word32 inLen, byte* out, word32 outLen, |
wolfSSL | 15:117db924cf7c | 2327 | enum wc_HashType hash, int mgf, int saltLen, |
wolfSSL | 15:117db924cf7c | 2328 | RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2329 | { |
wolfSSL | 15:117db924cf7c | 2330 | WC_RNG* rng = NULL; |
wolfSSL | 15:117db924cf7c | 2331 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 2332 | rng = key->rng; |
wolfSSL | 15:117db924cf7c | 2333 | #endif |
wolfSSL | 15:117db924cf7c | 2334 | return RsaPrivateDecryptEx(in, inLen, out, outLen, NULL, key, |
wolfSSL | 15:117db924cf7c | 2335 | RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, |
wolfSSL | 15:117db924cf7c | 2336 | hash, mgf, NULL, 0, saltLen, rng); |
wolfSSL | 15:117db924cf7c | 2337 | } |
wolfSSL | 15:117db924cf7c | 2338 | |
wolfSSL | 15:117db924cf7c | 2339 | |
wolfSSL | 15:117db924cf7c | 2340 | /* Checks the PSS data to ensure that the signature matches. |
wolfSSL | 15:117db924cf7c | 2341 | * Salt length is equal to hash length. |
wolfSSL | 15:117db924cf7c | 2342 | * |
wolfSSL | 15:117db924cf7c | 2343 | * in Hash of the data that is being verified. |
wolfSSL | 15:117db924cf7c | 2344 | * inSz Length of hash. |
wolfSSL | 15:117db924cf7c | 2345 | * sig Buffer holding PSS data. |
wolfSSL | 15:117db924cf7c | 2346 | * sigSz Size of PSS data. |
wolfSSL | 15:117db924cf7c | 2347 | * hashType Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2348 | * returns BAD_PADDING_E when the PSS data is invalid, BAD_FUNC_ARG when |
wolfSSL | 15:117db924cf7c | 2349 | * NULL is passed in to in or sig or inSz is not the same as the hash |
wolfSSL | 15:117db924cf7c | 2350 | * algorithm length and 0 on success. |
wolfSSL | 15:117db924cf7c | 2351 | */ |
wolfSSL | 15:117db924cf7c | 2352 | int wc_RsaPSS_CheckPadding(const byte* in, word32 inSz, byte* sig, |
wolfSSL | 15:117db924cf7c | 2353 | word32 sigSz, enum wc_HashType hashType) |
wolfSSL | 15:117db924cf7c | 2354 | { |
wolfSSL | 15:117db924cf7c | 2355 | return wc_RsaPSS_CheckPadding_ex(in, inSz, sig, sigSz, hashType, inSz, 0); |
wolfSSL | 15:117db924cf7c | 2356 | } |
wolfSSL | 15:117db924cf7c | 2357 | |
wolfSSL | 15:117db924cf7c | 2358 | /* Checks the PSS data to ensure that the signature matches. |
wolfSSL | 15:117db924cf7c | 2359 | * |
wolfSSL | 15:117db924cf7c | 2360 | * in Hash of the data that is being verified. |
wolfSSL | 15:117db924cf7c | 2361 | * inSz Length of hash. |
wolfSSL | 15:117db924cf7c | 2362 | * sig Buffer holding PSS data. |
wolfSSL | 15:117db924cf7c | 2363 | * sigSz Size of PSS data. |
wolfSSL | 15:117db924cf7c | 2364 | * hashType Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2365 | * saltLen Length of salt used. -1 indicates salt length is the same as the |
wolfSSL | 15:117db924cf7c | 2366 | * hash length. |
wolfSSL | 15:117db924cf7c | 2367 | * returns BAD_PADDING_E when the PSS data is invalid, BAD_FUNC_ARG when |
wolfSSL | 15:117db924cf7c | 2368 | * NULL is passed in to in or sig or inSz is not the same as the hash |
wolfSSL | 15:117db924cf7c | 2369 | * algorithm length and 0 on success. |
wolfSSL | 15:117db924cf7c | 2370 | */ |
wolfSSL | 15:117db924cf7c | 2371 | int wc_RsaPSS_CheckPadding_ex(const byte* in, word32 inSz, byte* sig, |
wolfSSL | 15:117db924cf7c | 2372 | word32 sigSz, enum wc_HashType hashType, |
wolfSSL | 15:117db924cf7c | 2373 | int saltLen, int bits) |
wolfSSL | 15:117db924cf7c | 2374 | { |
wolfSSL | 15:117db924cf7c | 2375 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 2376 | byte sigCheck[WC_MAX_DIGEST_SIZE*2 + RSA_PSS_PAD_SZ]; |
wolfSSL | 15:117db924cf7c | 2377 | |
wolfSSL | 15:117db924cf7c | 2378 | (void)bits; |
wolfSSL | 15:117db924cf7c | 2379 | |
wolfSSL | 15:117db924cf7c | 2380 | if (in == NULL || sig == NULL || |
wolfSSL | 15:117db924cf7c | 2381 | inSz != (word32)wc_HashGetDigestSize(hashType)) |
wolfSSL | 15:117db924cf7c | 2382 | ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2383 | |
wolfSSL | 15:117db924cf7c | 2384 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 2385 | if (saltLen == -1) { |
wolfSSL | 15:117db924cf7c | 2386 | saltLen = inSz; |
wolfSSL | 15:117db924cf7c | 2387 | #ifdef WOLFSSL_SHA512 |
wolfSSL | 15:117db924cf7c | 2388 | /* See FIPS 186-4 section 5.5 item (e). */ |
wolfSSL | 15:117db924cf7c | 2389 | if (bits == 1024 && inSz == WC_SHA512_DIGEST_SIZE) |
wolfSSL | 15:117db924cf7c | 2390 | saltLen = RSA_PSS_SALT_MAX_SZ; |
wolfSSL | 15:117db924cf7c | 2391 | #endif |
wolfSSL | 15:117db924cf7c | 2392 | } |
wolfSSL | 15:117db924cf7c | 2393 | else if (saltLen < -1 || (word32)saltLen > inSz) |
wolfSSL | 15:117db924cf7c | 2394 | ret = PSS_SALTLEN_E; |
wolfSSL | 15:117db924cf7c | 2395 | } |
wolfSSL | 15:117db924cf7c | 2396 | |
wolfSSL | 15:117db924cf7c | 2397 | /* Sig = Salt | Exp Hash */ |
wolfSSL | 15:117db924cf7c | 2398 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 2399 | if (sigSz != inSz + saltLen) |
wolfSSL | 15:117db924cf7c | 2400 | ret = BAD_PADDING_E; |
wolfSSL | 15:117db924cf7c | 2401 | } |
wolfSSL | 15:117db924cf7c | 2402 | |
wolfSSL | 15:117db924cf7c | 2403 | /* Exp Hash = HASH(8 * 0x00 | Message Hash | Salt) */ |
wolfSSL | 15:117db924cf7c | 2404 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 2405 | XMEMSET(sigCheck, 0, RSA_PSS_PAD_SZ); |
wolfSSL | 15:117db924cf7c | 2406 | XMEMCPY(sigCheck + RSA_PSS_PAD_SZ, in, inSz); |
wolfSSL | 15:117db924cf7c | 2407 | XMEMCPY(sigCheck + RSA_PSS_PAD_SZ + inSz, sig, saltLen); |
wolfSSL | 15:117db924cf7c | 2408 | ret = wc_Hash(hashType, sigCheck, RSA_PSS_PAD_SZ + inSz + saltLen, |
wolfSSL | 15:117db924cf7c | 2409 | sigCheck, inSz); |
wolfSSL | 15:117db924cf7c | 2410 | } |
wolfSSL | 15:117db924cf7c | 2411 | if (ret == 0) { |
wolfSSL | 15:117db924cf7c | 2412 | if (XMEMCMP(sigCheck, sig + saltLen, inSz) != 0) { |
wolfSSL | 15:117db924cf7c | 2413 | WOLFSSL_MSG("RsaPSS_CheckPadding: Padding Error"); |
wolfSSL | 15:117db924cf7c | 2414 | ret = BAD_PADDING_E; |
wolfSSL | 15:117db924cf7c | 2415 | } |
wolfSSL | 15:117db924cf7c | 2416 | } |
wolfSSL | 15:117db924cf7c | 2417 | |
wolfSSL | 15:117db924cf7c | 2418 | return ret; |
wolfSSL | 15:117db924cf7c | 2419 | } |
wolfSSL | 15:117db924cf7c | 2420 | |
wolfSSL | 15:117db924cf7c | 2421 | |
wolfSSL | 15:117db924cf7c | 2422 | /* Verify the message signed with RSA-PSS. |
wolfSSL | 15:117db924cf7c | 2423 | * The input buffer is reused for the ouput buffer. |
wolfSSL | 15:117db924cf7c | 2424 | * Salt length is equal to hash length. |
wolfSSL | 15:117db924cf7c | 2425 | * |
wolfSSL | 15:117db924cf7c | 2426 | * in Buffer holding encrypted data. |
wolfSSL | 15:117db924cf7c | 2427 | * inLen Length of data in buffer. |
wolfSSL | 15:117db924cf7c | 2428 | * out Pointer to address containing the PSS data. |
wolfSSL | 15:117db924cf7c | 2429 | * digest Hash of the data that is being verified. |
wolfSSL | 15:117db924cf7c | 2430 | * digestLen Length of hash. |
wolfSSL | 15:117db924cf7c | 2431 | * hash Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2432 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 2433 | * key Public RSA key. |
wolfSSL | 15:117db924cf7c | 2434 | * returns the length of the PSS data on success and negative indicates failure. |
wolfSSL | 15:117db924cf7c | 2435 | */ |
wolfSSL | 15:117db924cf7c | 2436 | int wc_RsaPSS_VerifyCheckInline(byte* in, word32 inLen, byte** out, |
wolfSSL | 15:117db924cf7c | 2437 | const byte* digest, word32 digestLen, |
wolfSSL | 15:117db924cf7c | 2438 | enum wc_HashType hash, int mgf, RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2439 | { |
wolfSSL | 15:117db924cf7c | 2440 | int ret = 0, verify, saltLen, hLen, bits = 0; |
wolfSSL | 15:117db924cf7c | 2441 | |
wolfSSL | 15:117db924cf7c | 2442 | hLen = wc_HashGetDigestSize(hash); |
wolfSSL | 15:117db924cf7c | 2443 | if (hLen < 0) |
wolfSSL | 15:117db924cf7c | 2444 | return hLen; |
wolfSSL | 15:117db924cf7c | 2445 | if ((word32)hLen != digestLen) |
wolfSSL | 15:117db924cf7c | 2446 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2447 | |
wolfSSL | 15:117db924cf7c | 2448 | saltLen = hLen; |
wolfSSL | 15:117db924cf7c | 2449 | #ifdef WOLFSSL_SHA512 |
wolfSSL | 15:117db924cf7c | 2450 | /* See FIPS 186-4 section 5.5 item (e). */ |
wolfSSL | 15:117db924cf7c | 2451 | bits = mp_count_bits(&key->n); |
wolfSSL | 15:117db924cf7c | 2452 | if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE) |
wolfSSL | 15:117db924cf7c | 2453 | saltLen = RSA_PSS_SALT_MAX_SZ; |
wolfSSL | 15:117db924cf7c | 2454 | #endif |
wolfSSL | 15:117db924cf7c | 2455 | |
wolfSSL | 15:117db924cf7c | 2456 | verify = wc_RsaPSS_VerifyInline_ex(in, inLen, out, hash, mgf, saltLen, key); |
wolfSSL | 15:117db924cf7c | 2457 | if (verify > 0) |
wolfSSL | 15:117db924cf7c | 2458 | ret = wc_RsaPSS_CheckPadding_ex(digest, digestLen, *out, verify, |
wolfSSL | 15:117db924cf7c | 2459 | hash, saltLen, bits); |
wolfSSL | 15:117db924cf7c | 2460 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2461 | ret = verify; |
wolfSSL | 15:117db924cf7c | 2462 | |
wolfSSL | 15:117db924cf7c | 2463 | return ret; |
wolfSSL | 15:117db924cf7c | 2464 | } |
wolfSSL | 15:117db924cf7c | 2465 | |
wolfSSL | 15:117db924cf7c | 2466 | |
wolfSSL | 15:117db924cf7c | 2467 | /* Verify the message signed with RSA-PSS. |
wolfSSL | 15:117db924cf7c | 2468 | * Salt length is equal to hash length. |
wolfSSL | 15:117db924cf7c | 2469 | * |
wolfSSL | 15:117db924cf7c | 2470 | * in Buffer holding encrypted data. |
wolfSSL | 15:117db924cf7c | 2471 | * inLen Length of data in buffer. |
wolfSSL | 15:117db924cf7c | 2472 | * out Pointer to address containing the PSS data. |
wolfSSL | 15:117db924cf7c | 2473 | * outLen Length of the output. |
wolfSSL | 15:117db924cf7c | 2474 | * digest Hash of the data that is being verified. |
wolfSSL | 15:117db924cf7c | 2475 | * digestLen Length of hash. |
wolfSSL | 15:117db924cf7c | 2476 | * hash Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2477 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 2478 | * key Public RSA key. |
wolfSSL | 15:117db924cf7c | 2479 | * returns the length of the PSS data on success and negative indicates failure. |
wolfSSL | 15:117db924cf7c | 2480 | */ |
wolfSSL | 15:117db924cf7c | 2481 | int wc_RsaPSS_VerifyCheck(byte* in, word32 inLen, byte* out, word32 outLen, |
wolfSSL | 15:117db924cf7c | 2482 | const byte* digest, word32 digestLen, |
wolfSSL | 15:117db924cf7c | 2483 | enum wc_HashType hash, int mgf, |
wolfSSL | 15:117db924cf7c | 2484 | RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2485 | { |
wolfSSL | 15:117db924cf7c | 2486 | int ret = 0, verify, saltLen, hLen, bits = 0; |
wolfSSL | 15:117db924cf7c | 2487 | |
wolfSSL | 15:117db924cf7c | 2488 | hLen = wc_HashGetDigestSize(hash); |
wolfSSL | 15:117db924cf7c | 2489 | if (hLen < 0) |
wolfSSL | 15:117db924cf7c | 2490 | return hLen; |
wolfSSL | 15:117db924cf7c | 2491 | if ((word32)hLen != digestLen) |
wolfSSL | 15:117db924cf7c | 2492 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2493 | |
wolfSSL | 15:117db924cf7c | 2494 | saltLen = hLen; |
wolfSSL | 15:117db924cf7c | 2495 | #ifdef WOLFSSL_SHA512 |
wolfSSL | 15:117db924cf7c | 2496 | /* See FIPS 186-4 section 5.5 item (e). */ |
wolfSSL | 15:117db924cf7c | 2497 | bits = mp_count_bits(&key->n); |
wolfSSL | 15:117db924cf7c | 2498 | if (bits == 1024 && hLen == WC_SHA512_DIGEST_SIZE) |
wolfSSL | 15:117db924cf7c | 2499 | saltLen = RSA_PSS_SALT_MAX_SZ; |
wolfSSL | 15:117db924cf7c | 2500 | #endif |
wolfSSL | 15:117db924cf7c | 2501 | |
wolfSSL | 15:117db924cf7c | 2502 | verify = wc_RsaPSS_Verify_ex(in, inLen, out, outLen, hash, |
wolfSSL | 15:117db924cf7c | 2503 | mgf, saltLen, key); |
wolfSSL | 15:117db924cf7c | 2504 | if (verify > 0) |
wolfSSL | 15:117db924cf7c | 2505 | ret = wc_RsaPSS_CheckPadding_ex(digest, digestLen, out, verify, |
wolfSSL | 15:117db924cf7c | 2506 | hash, saltLen, bits); |
wolfSSL | 15:117db924cf7c | 2507 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2508 | ret = verify; |
wolfSSL | 15:117db924cf7c | 2509 | |
wolfSSL | 15:117db924cf7c | 2510 | return ret; |
wolfSSL | 15:117db924cf7c | 2511 | } |
wolfSSL | 15:117db924cf7c | 2512 | |
wolfSSL | 15:117db924cf7c | 2513 | #endif |
wolfSSL | 15:117db924cf7c | 2514 | |
wolfSSL | 15:117db924cf7c | 2515 | int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, |
wolfSSL | 15:117db924cf7c | 2516 | RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 2517 | { |
wolfSSL | 15:117db924cf7c | 2518 | return RsaPublicEncryptEx(in, inLen, out, outLen, key, |
wolfSSL | 15:117db924cf7c | 2519 | RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, |
wolfSSL | 15:117db924cf7c | 2520 | WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0, 0, rng); |
wolfSSL | 15:117db924cf7c | 2521 | } |
wolfSSL | 15:117db924cf7c | 2522 | |
wolfSSL | 15:117db924cf7c | 2523 | #ifdef WC_RSA_PSS |
wolfSSL | 15:117db924cf7c | 2524 | /* Sign the hash of a message using RSA-PSS. |
wolfSSL | 15:117db924cf7c | 2525 | * Salt length is equal to hash length. |
wolfSSL | 15:117db924cf7c | 2526 | * |
wolfSSL | 15:117db924cf7c | 2527 | * in Buffer holding hash of message. |
wolfSSL | 15:117db924cf7c | 2528 | * inLen Length of data in buffer (hash length). |
wolfSSL | 15:117db924cf7c | 2529 | * out Buffer to write encrypted signature into. |
wolfSSL | 15:117db924cf7c | 2530 | * outLen Size of buffer to write to. |
wolfSSL | 15:117db924cf7c | 2531 | * hash Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2532 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 2533 | * key Public RSA key. |
wolfSSL | 15:117db924cf7c | 2534 | * rng Random number generator. |
wolfSSL | 15:117db924cf7c | 2535 | * returns the length of the encrypted signature on success, a negative value |
wolfSSL | 15:117db924cf7c | 2536 | * indicates failure. |
wolfSSL | 15:117db924cf7c | 2537 | */ |
wolfSSL | 15:117db924cf7c | 2538 | int wc_RsaPSS_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, |
wolfSSL | 15:117db924cf7c | 2539 | enum wc_HashType hash, int mgf, RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 2540 | { |
wolfSSL | 15:117db924cf7c | 2541 | return wc_RsaPSS_Sign_ex(in, inLen, out, outLen, hash, mgf, -1, key, rng); |
wolfSSL | 15:117db924cf7c | 2542 | } |
wolfSSL | 15:117db924cf7c | 2543 | |
wolfSSL | 15:117db924cf7c | 2544 | /* Sign the hash of a message using RSA-PSS. |
wolfSSL | 15:117db924cf7c | 2545 | * |
wolfSSL | 15:117db924cf7c | 2546 | * in Buffer holding hash of message. |
wolfSSL | 15:117db924cf7c | 2547 | * inLen Length of data in buffer (hash length). |
wolfSSL | 15:117db924cf7c | 2548 | * out Buffer to write encrypted signature into. |
wolfSSL | 15:117db924cf7c | 2549 | * outLen Size of buffer to write to. |
wolfSSL | 15:117db924cf7c | 2550 | * hash Hash algorithm. |
wolfSSL | 15:117db924cf7c | 2551 | * mgf Mask generation function. |
wolfSSL | 15:117db924cf7c | 2552 | * saltLen Length of salt used. -1 indicates salt length is the same as the |
wolfSSL | 15:117db924cf7c | 2553 | * hash length. |
wolfSSL | 15:117db924cf7c | 2554 | * key Public RSA key. |
wolfSSL | 15:117db924cf7c | 2555 | * rng Random number generator. |
wolfSSL | 15:117db924cf7c | 2556 | * returns the length of the encrypted signature on success, a negative value |
wolfSSL | 15:117db924cf7c | 2557 | * indicates failure. |
wolfSSL | 15:117db924cf7c | 2558 | */ |
wolfSSL | 15:117db924cf7c | 2559 | int wc_RsaPSS_Sign_ex(const byte* in, word32 inLen, byte* out, word32 outLen, |
wolfSSL | 15:117db924cf7c | 2560 | enum wc_HashType hash, int mgf, int saltLen, RsaKey* key, |
wolfSSL | 15:117db924cf7c | 2561 | WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 2562 | { |
wolfSSL | 15:117db924cf7c | 2563 | return RsaPublicEncryptEx(in, inLen, out, outLen, key, |
wolfSSL | 15:117db924cf7c | 2564 | RSA_PRIVATE_ENCRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, |
wolfSSL | 15:117db924cf7c | 2565 | hash, mgf, NULL, 0, saltLen, rng); |
wolfSSL | 15:117db924cf7c | 2566 | } |
wolfSSL | 15:117db924cf7c | 2567 | #endif |
wolfSSL | 15:117db924cf7c | 2568 | |
wolfSSL | 15:117db924cf7c | 2569 | int wc_RsaEncryptSize(RsaKey* key) |
wolfSSL | 15:117db924cf7c | 2570 | { |
wolfSSL | 15:117db924cf7c | 2571 | int ret; |
wolfSSL | 15:117db924cf7c | 2572 | |
wolfSSL | 15:117db924cf7c | 2573 | if (key == NULL) { |
wolfSSL | 15:117db924cf7c | 2574 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2575 | } |
wolfSSL | 15:117db924cf7c | 2576 | |
wolfSSL | 15:117db924cf7c | 2577 | ret = mp_unsigned_bin_size(&key->n); |
wolfSSL | 15:117db924cf7c | 2578 | |
wolfSSL | 15:117db924cf7c | 2579 | #ifdef WOLF_CRYPTO_DEV |
wolfSSL | 15:117db924cf7c | 2580 | if (ret == 0 && key->devId != INVALID_DEVID) { |
wolfSSL | 15:117db924cf7c | 2581 | ret = 2048/8; /* hardware handles, use 2048-bit as default */ |
wolfSSL | 15:117db924cf7c | 2582 | } |
wolfSSL | 15:117db924cf7c | 2583 | #endif |
wolfSSL | 15:117db924cf7c | 2584 | |
wolfSSL | 15:117db924cf7c | 2585 | return ret; |
wolfSSL | 15:117db924cf7c | 2586 | } |
wolfSSL | 15:117db924cf7c | 2587 | |
wolfSSL | 15:117db924cf7c | 2588 | |
wolfSSL | 15:117db924cf7c | 2589 | /* flatten RsaKey structure into individual elements (e, n) */ |
wolfSSL | 15:117db924cf7c | 2590 | int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n, |
wolfSSL | 15:117db924cf7c | 2591 | word32* nSz) |
wolfSSL | 15:117db924cf7c | 2592 | { |
wolfSSL | 15:117db924cf7c | 2593 | int sz, ret; |
wolfSSL | 15:117db924cf7c | 2594 | |
wolfSSL | 15:117db924cf7c | 2595 | if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL) { |
wolfSSL | 15:117db924cf7c | 2596 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2597 | } |
wolfSSL | 15:117db924cf7c | 2598 | |
wolfSSL | 15:117db924cf7c | 2599 | sz = mp_unsigned_bin_size(&key->e); |
wolfSSL | 15:117db924cf7c | 2600 | if ((word32)sz > *eSz) |
wolfSSL | 15:117db924cf7c | 2601 | return RSA_BUFFER_E; |
wolfSSL | 15:117db924cf7c | 2602 | ret = mp_to_unsigned_bin(&key->e, e); |
wolfSSL | 15:117db924cf7c | 2603 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2604 | return ret; |
wolfSSL | 15:117db924cf7c | 2605 | *eSz = (word32)sz; |
wolfSSL | 15:117db924cf7c | 2606 | |
wolfSSL | 15:117db924cf7c | 2607 | sz = wc_RsaEncryptSize(key); |
wolfSSL | 15:117db924cf7c | 2608 | if ((word32)sz > *nSz) |
wolfSSL | 15:117db924cf7c | 2609 | return RSA_BUFFER_E; |
wolfSSL | 15:117db924cf7c | 2610 | ret = mp_to_unsigned_bin(&key->n, n); |
wolfSSL | 15:117db924cf7c | 2611 | if (ret != MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2612 | return ret; |
wolfSSL | 15:117db924cf7c | 2613 | *nSz = (word32)sz; |
wolfSSL | 15:117db924cf7c | 2614 | |
wolfSSL | 15:117db924cf7c | 2615 | return 0; |
wolfSSL | 15:117db924cf7c | 2616 | } |
wolfSSL | 15:117db924cf7c | 2617 | |
wolfSSL | 15:117db924cf7c | 2618 | |
wolfSSL | 15:117db924cf7c | 2619 | static int RsaGetValue(mp_int* in, byte* out, word32* outSz) |
wolfSSL | 15:117db924cf7c | 2620 | { |
wolfSSL | 15:117db924cf7c | 2621 | word32 sz; |
wolfSSL | 15:117db924cf7c | 2622 | int ret = 0; |
wolfSSL | 15:117db924cf7c | 2623 | |
wolfSSL | 15:117db924cf7c | 2624 | /* Parameters ensured by calling function. */ |
wolfSSL | 15:117db924cf7c | 2625 | |
wolfSSL | 15:117db924cf7c | 2626 | sz = (word32)mp_unsigned_bin_size(in); |
wolfSSL | 15:117db924cf7c | 2627 | if (sz > *outSz) |
wolfSSL | 15:117db924cf7c | 2628 | ret = RSA_BUFFER_E; |
wolfSSL | 15:117db924cf7c | 2629 | |
wolfSSL | 15:117db924cf7c | 2630 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2631 | ret = mp_to_unsigned_bin(in, out); |
wolfSSL | 15:117db924cf7c | 2632 | |
wolfSSL | 15:117db924cf7c | 2633 | if (ret == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2634 | *outSz = sz; |
wolfSSL | 15:117db924cf7c | 2635 | |
wolfSSL | 15:117db924cf7c | 2636 | return ret; |
wolfSSL | 15:117db924cf7c | 2637 | } |
wolfSSL | 15:117db924cf7c | 2638 | |
wolfSSL | 15:117db924cf7c | 2639 | |
wolfSSL | 15:117db924cf7c | 2640 | int wc_RsaExportKey(RsaKey* key, |
wolfSSL | 15:117db924cf7c | 2641 | byte* e, word32* eSz, byte* n, word32* nSz, |
wolfSSL | 15:117db924cf7c | 2642 | byte* d, word32* dSz, byte* p, word32* pSz, |
wolfSSL | 15:117db924cf7c | 2643 | byte* q, word32* qSz) |
wolfSSL | 15:117db924cf7c | 2644 | { |
wolfSSL | 15:117db924cf7c | 2645 | int ret = BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2646 | |
wolfSSL | 15:117db924cf7c | 2647 | if (key && e && eSz && n && nSz && d && dSz && p && pSz && q && qSz) |
wolfSSL | 15:117db924cf7c | 2648 | ret = 0; |
wolfSSL | 15:117db924cf7c | 2649 | |
wolfSSL | 15:117db924cf7c | 2650 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2651 | ret = RsaGetValue(&key->e, e, eSz); |
wolfSSL | 15:117db924cf7c | 2652 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2653 | ret = RsaGetValue(&key->n, n, nSz); |
wolfSSL | 15:117db924cf7c | 2654 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2655 | ret = RsaGetValue(&key->d, d, dSz); |
wolfSSL | 15:117db924cf7c | 2656 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2657 | ret = RsaGetValue(&key->p, p, pSz); |
wolfSSL | 15:117db924cf7c | 2658 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2659 | ret = RsaGetValue(&key->q, q, qSz); |
wolfSSL | 15:117db924cf7c | 2660 | |
wolfSSL | 15:117db924cf7c | 2661 | return ret; |
wolfSSL | 15:117db924cf7c | 2662 | } |
wolfSSL | 15:117db924cf7c | 2663 | |
wolfSSL | 15:117db924cf7c | 2664 | |
wolfSSL | 15:117db924cf7c | 2665 | #ifdef WOLFSSL_KEY_GEN |
wolfSSL | 15:117db924cf7c | 2666 | |
wolfSSL | 15:117db924cf7c | 2667 | /* Check that |p-q| > 2^((size/2)-100) */ |
wolfSSL | 15:117db924cf7c | 2668 | static int wc_CompareDiffPQ(mp_int* p, mp_int* q, int size) |
wolfSSL | 15:117db924cf7c | 2669 | { |
wolfSSL | 15:117db924cf7c | 2670 | mp_int c, d; |
wolfSSL | 15:117db924cf7c | 2671 | int ret; |
wolfSSL | 15:117db924cf7c | 2672 | |
wolfSSL | 15:117db924cf7c | 2673 | if (p == NULL || q == NULL) |
wolfSSL | 15:117db924cf7c | 2674 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2675 | |
wolfSSL | 15:117db924cf7c | 2676 | ret = mp_init_multi(&c, &d, NULL, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 2677 | |
wolfSSL | 15:117db924cf7c | 2678 | /* c = 2^((size/2)-100) */ |
wolfSSL | 15:117db924cf7c | 2679 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2680 | ret = mp_2expt(&c, (size/2)-100); |
wolfSSL | 15:117db924cf7c | 2681 | |
wolfSSL | 15:117db924cf7c | 2682 | /* d = |p-q| */ |
wolfSSL | 15:117db924cf7c | 2683 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2684 | ret = mp_sub(p, q, &d); |
wolfSSL | 15:117db924cf7c | 2685 | |
wolfSSL | 15:117db924cf7c | 2686 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2687 | ret = mp_abs(&d, &d); |
wolfSSL | 15:117db924cf7c | 2688 | |
wolfSSL | 15:117db924cf7c | 2689 | /* compare */ |
wolfSSL | 15:117db924cf7c | 2690 | if (ret == 0) |
wolfSSL | 15:117db924cf7c | 2691 | ret = mp_cmp(&d, &c); |
wolfSSL | 15:117db924cf7c | 2692 | |
wolfSSL | 15:117db924cf7c | 2693 | if (ret == MP_GT) |
wolfSSL | 15:117db924cf7c | 2694 | ret = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 2695 | |
wolfSSL | 15:117db924cf7c | 2696 | mp_clear(&d); |
wolfSSL | 15:117db924cf7c | 2697 | mp_clear(&c); |
wolfSSL | 15:117db924cf7c | 2698 | |
wolfSSL | 15:117db924cf7c | 2699 | return ret; |
wolfSSL | 15:117db924cf7c | 2700 | } |
wolfSSL | 15:117db924cf7c | 2701 | |
wolfSSL | 15:117db924cf7c | 2702 | |
wolfSSL | 15:117db924cf7c | 2703 | /* The lower_bound value is floor(2^(0.5) * 2^((nlen/2)-1)) where nlen is 4096. |
wolfSSL | 15:117db924cf7c | 2704 | * This number was calculated using a small test tool written with a common |
wolfSSL | 15:117db924cf7c | 2705 | * large number math library. Other values of nlen may be checked with a subset |
wolfSSL | 15:117db924cf7c | 2706 | * of lower_bound. */ |
wolfSSL | 15:117db924cf7c | 2707 | static const byte lower_bound[] = { |
wolfSSL | 15:117db924cf7c | 2708 | 0xB5, 0x04, 0xF3, 0x33, 0xF9, 0xDE, 0x64, 0x84, |
wolfSSL | 15:117db924cf7c | 2709 | 0x59, 0x7D, 0x89, 0xB3, 0x75, 0x4A, 0xBE, 0x9F, |
wolfSSL | 15:117db924cf7c | 2710 | 0x1D, 0x6F, 0x60, 0xBA, 0x89, 0x3B, 0xA8, 0x4C, |
wolfSSL | 15:117db924cf7c | 2711 | 0xED, 0x17, 0xAC, 0x85, 0x83, 0x33, 0x99, 0x15, |
wolfSSL | 15:117db924cf7c | 2712 | /* 512 */ |
wolfSSL | 15:117db924cf7c | 2713 | 0x4A, 0xFC, 0x83, 0x04, 0x3A, 0xB8, 0xA2, 0xC3, |
wolfSSL | 15:117db924cf7c | 2714 | 0xA8, 0xB1, 0xFE, 0x6F, 0xDC, 0x83, 0xDB, 0x39, |
wolfSSL | 15:117db924cf7c | 2715 | 0x0F, 0x74, 0xA8, 0x5E, 0x43, 0x9C, 0x7B, 0x4A, |
wolfSSL | 15:117db924cf7c | 2716 | 0x78, 0x04, 0x87, 0x36, 0x3D, 0xFA, 0x27, 0x68, |
wolfSSL | 15:117db924cf7c | 2717 | /* 1024 */ |
wolfSSL | 15:117db924cf7c | 2718 | 0xD2, 0x20, 0x2E, 0x87, 0x42, 0xAF, 0x1F, 0x4E, |
wolfSSL | 15:117db924cf7c | 2719 | 0x53, 0x05, 0x9C, 0x60, 0x11, 0xBC, 0x33, 0x7B, |
wolfSSL | 15:117db924cf7c | 2720 | 0xCA, 0xB1, 0xBC, 0x91, 0x16, 0x88, 0x45, 0x8A, |
wolfSSL | 15:117db924cf7c | 2721 | 0x46, 0x0A, 0xBC, 0x72, 0x2F, 0x7C, 0x4E, 0x33, |
wolfSSL | 15:117db924cf7c | 2722 | 0xC6, 0xD5, 0xA8, 0xA3, 0x8B, 0xB7, 0xE9, 0xDC, |
wolfSSL | 15:117db924cf7c | 2723 | 0xCB, 0x2A, 0x63, 0x43, 0x31, 0xF3, 0xC8, 0x4D, |
wolfSSL | 15:117db924cf7c | 2724 | 0xF5, 0x2F, 0x12, 0x0F, 0x83, 0x6E, 0x58, 0x2E, |
wolfSSL | 15:117db924cf7c | 2725 | 0xEA, 0xA4, 0xA0, 0x89, 0x90, 0x40, 0xCA, 0x4A, |
wolfSSL | 15:117db924cf7c | 2726 | /* 2048 */ |
wolfSSL | 15:117db924cf7c | 2727 | 0x81, 0x39, 0x4A, 0xB6, 0xD8, 0xFD, 0x0E, 0xFD, |
wolfSSL | 15:117db924cf7c | 2728 | 0xF4, 0xD3, 0xA0, 0x2C, 0xEB, 0xC9, 0x3E, 0x0C, |
wolfSSL | 15:117db924cf7c | 2729 | 0x42, 0x64, 0xDA, 0xBC, 0xD5, 0x28, 0xB6, 0x51, |
wolfSSL | 15:117db924cf7c | 2730 | 0xB8, 0xCF, 0x34, 0x1B, 0x6F, 0x82, 0x36, 0xC7, |
wolfSSL | 15:117db924cf7c | 2731 | 0x01, 0x04, 0xDC, 0x01, 0xFE, 0x32, 0x35, 0x2F, |
wolfSSL | 15:117db924cf7c | 2732 | 0x33, 0x2A, 0x5E, 0x9F, 0x7B, 0xDA, 0x1E, 0xBF, |
wolfSSL | 15:117db924cf7c | 2733 | 0xF6, 0xA1, 0xBE, 0x3F, 0xCA, 0x22, 0x13, 0x07, |
wolfSSL | 15:117db924cf7c | 2734 | 0xDE, 0xA0, 0x62, 0x41, 0xF7, 0xAA, 0x81, 0xC2, |
wolfSSL | 15:117db924cf7c | 2735 | /* 3072 */ |
wolfSSL | 15:117db924cf7c | 2736 | 0xC1, 0xFC, 0xBD, 0xDE, 0xA2, 0xF7, 0xDC, 0x33, |
wolfSSL | 15:117db924cf7c | 2737 | 0x18, 0x83, 0x8A, 0x2E, 0xAF, 0xF5, 0xF3, 0xB2, |
wolfSSL | 15:117db924cf7c | 2738 | 0xD2, 0x4F, 0x4A, 0x76, 0x3F, 0xAC, 0xB8, 0x82, |
wolfSSL | 15:117db924cf7c | 2739 | 0xFD, 0xFE, 0x17, 0x0F, 0xD3, 0xB1, 0xF7, 0x80, |
wolfSSL | 15:117db924cf7c | 2740 | 0xF9, 0xAC, 0xCE, 0x41, 0x79, 0x7F, 0x28, 0x05, |
wolfSSL | 15:117db924cf7c | 2741 | 0xC2, 0x46, 0x78, 0x5E, 0x92, 0x95, 0x70, 0x23, |
wolfSSL | 15:117db924cf7c | 2742 | 0x5F, 0xCF, 0x8F, 0x7B, 0xCA, 0x3E, 0xA3, 0x3B, |
wolfSSL | 15:117db924cf7c | 2743 | 0x4D, 0x7C, 0x60, 0xA5, 0xE6, 0x33, 0xE3, 0xE1 |
wolfSSL | 15:117db924cf7c | 2744 | /* 4096 */ |
wolfSSL | 15:117db924cf7c | 2745 | }; |
wolfSSL | 15:117db924cf7c | 2746 | |
wolfSSL | 15:117db924cf7c | 2747 | |
wolfSSL | 15:117db924cf7c | 2748 | /* returns 1 on key size ok and 0 if not ok */ |
wolfSSL | 15:117db924cf7c | 2749 | static WC_INLINE int RsaSizeCheck(int size) |
wolfSSL | 15:117db924cf7c | 2750 | { |
wolfSSL | 15:117db924cf7c | 2751 | if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE) { |
wolfSSL | 15:117db924cf7c | 2752 | return 0; |
wolfSSL | 15:117db924cf7c | 2753 | } |
wolfSSL | 15:117db924cf7c | 2754 | |
wolfSSL | 15:117db924cf7c | 2755 | #ifdef HAVE_FIPS |
wolfSSL | 15:117db924cf7c | 2756 | /* Key size requirements for CAVP */ |
wolfSSL | 15:117db924cf7c | 2757 | switch (size) { |
wolfSSL | 15:117db924cf7c | 2758 | case 1024: |
wolfSSL | 15:117db924cf7c | 2759 | case 2048: |
wolfSSL | 15:117db924cf7c | 2760 | case 3072: |
wolfSSL | 15:117db924cf7c | 2761 | case 4096: |
wolfSSL | 15:117db924cf7c | 2762 | return 1; |
wolfSSL | 15:117db924cf7c | 2763 | } |
wolfSSL | 15:117db924cf7c | 2764 | |
wolfSSL | 15:117db924cf7c | 2765 | return 0; |
wolfSSL | 15:117db924cf7c | 2766 | #else |
wolfSSL | 15:117db924cf7c | 2767 | return 1; /* allow unusual key sizes in non FIPS mode */ |
wolfSSL | 15:117db924cf7c | 2768 | #endif /* HAVE_FIPS */ |
wolfSSL | 15:117db924cf7c | 2769 | } |
wolfSSL | 15:117db924cf7c | 2770 | |
wolfSSL | 15:117db924cf7c | 2771 | |
wolfSSL | 15:117db924cf7c | 2772 | static int wc_CheckProbablePrime_ex(mp_int* p, mp_int* q, mp_int* e, int nlen, |
wolfSSL | 15:117db924cf7c | 2773 | int* isPrime) |
wolfSSL | 15:117db924cf7c | 2774 | { |
wolfSSL | 15:117db924cf7c | 2775 | int ret; |
wolfSSL | 15:117db924cf7c | 2776 | mp_int tmp1, tmp2; |
wolfSSL | 15:117db924cf7c | 2777 | mp_int* prime; |
wolfSSL | 15:117db924cf7c | 2778 | |
wolfSSL | 15:117db924cf7c | 2779 | if (p == NULL || e == NULL || isPrime == NULL) |
wolfSSL | 15:117db924cf7c | 2780 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2781 | |
wolfSSL | 15:117db924cf7c | 2782 | if (!RsaSizeCheck(nlen)) |
wolfSSL | 15:117db924cf7c | 2783 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2784 | |
wolfSSL | 15:117db924cf7c | 2785 | *isPrime = MP_NO; |
wolfSSL | 15:117db924cf7c | 2786 | |
wolfSSL | 15:117db924cf7c | 2787 | if (q != NULL) { |
wolfSSL | 15:117db924cf7c | 2788 | /* 5.4 - check that |p-q| <= (2^(1/2))(2^((nlen/2)-1)) */ |
wolfSSL | 15:117db924cf7c | 2789 | ret = wc_CompareDiffPQ(p, q, nlen); |
wolfSSL | 15:117db924cf7c | 2790 | if (ret != MP_OKAY) goto notOkay; |
wolfSSL | 15:117db924cf7c | 2791 | prime = q; |
wolfSSL | 15:117db924cf7c | 2792 | } |
wolfSSL | 15:117db924cf7c | 2793 | else |
wolfSSL | 15:117db924cf7c | 2794 | prime = p; |
wolfSSL | 15:117db924cf7c | 2795 | |
wolfSSL | 15:117db924cf7c | 2796 | ret = mp_init_multi(&tmp1, &tmp2, NULL, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 2797 | if (ret != MP_OKAY) goto notOkay; |
wolfSSL | 15:117db924cf7c | 2798 | |
wolfSSL | 15:117db924cf7c | 2799 | /* 4.4,5.5 - Check that prime >= (2^(1/2))(2^((nlen/2)-1)) |
wolfSSL | 15:117db924cf7c | 2800 | * This is a comparison against lowerBound */ |
wolfSSL | 15:117db924cf7c | 2801 | ret = mp_read_unsigned_bin(&tmp1, lower_bound, nlen/16); |
wolfSSL | 15:117db924cf7c | 2802 | if (ret != MP_OKAY) goto notOkay; |
wolfSSL | 15:117db924cf7c | 2803 | ret = mp_cmp(prime, &tmp1); |
wolfSSL | 15:117db924cf7c | 2804 | if (ret == MP_LT) goto exit; |
wolfSSL | 15:117db924cf7c | 2805 | |
wolfSSL | 15:117db924cf7c | 2806 | /* 4.5,5.6 - Check that GCD(p-1, e) == 1 */ |
wolfSSL | 15:117db924cf7c | 2807 | ret = mp_sub_d(prime, 1, &tmp1); /* tmp1 = prime-1 */ |
wolfSSL | 15:117db924cf7c | 2808 | if (ret != MP_OKAY) goto notOkay; |
wolfSSL | 15:117db924cf7c | 2809 | ret = mp_gcd(&tmp1, e, &tmp2); /* tmp2 = gcd(prime-1, e) */ |
wolfSSL | 15:117db924cf7c | 2810 | if (ret != MP_OKAY) goto notOkay; |
wolfSSL | 15:117db924cf7c | 2811 | ret = mp_cmp_d(&tmp2, 1); |
wolfSSL | 15:117db924cf7c | 2812 | if (ret != MP_EQ) goto exit; /* e divides p-1 */ |
wolfSSL | 15:117db924cf7c | 2813 | |
wolfSSL | 15:117db924cf7c | 2814 | /* 4.5.1,5.6.1 - Check primality of p with 8 iterations */ |
wolfSSL | 15:117db924cf7c | 2815 | ret = mp_prime_is_prime(prime, 8, isPrime); |
wolfSSL | 15:117db924cf7c | 2816 | /* Performs some divides by a table of primes, and then does M-R, |
wolfSSL | 15:117db924cf7c | 2817 | * it sets isPrime as a side-effect. */ |
wolfSSL | 15:117db924cf7c | 2818 | if (ret != MP_OKAY) goto notOkay; |
wolfSSL | 15:117db924cf7c | 2819 | |
wolfSSL | 15:117db924cf7c | 2820 | exit: |
wolfSSL | 15:117db924cf7c | 2821 | ret = MP_OKAY; |
wolfSSL | 15:117db924cf7c | 2822 | notOkay: |
wolfSSL | 15:117db924cf7c | 2823 | mp_clear(&tmp1); |
wolfSSL | 15:117db924cf7c | 2824 | mp_clear(&tmp2); |
wolfSSL | 15:117db924cf7c | 2825 | return ret; |
wolfSSL | 15:117db924cf7c | 2826 | } |
wolfSSL | 15:117db924cf7c | 2827 | |
wolfSSL | 15:117db924cf7c | 2828 | |
wolfSSL | 15:117db924cf7c | 2829 | |
wolfSSL | 15:117db924cf7c | 2830 | int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz, |
wolfSSL | 15:117db924cf7c | 2831 | const byte* qRaw, word32 qRawSz, |
wolfSSL | 15:117db924cf7c | 2832 | const byte* eRaw, word32 eRawSz, |
wolfSSL | 15:117db924cf7c | 2833 | int nlen, int* isPrime) |
wolfSSL | 15:117db924cf7c | 2834 | { |
wolfSSL | 15:117db924cf7c | 2835 | mp_int p, q, e; |
wolfSSL | 15:117db924cf7c | 2836 | mp_int* Q = NULL; |
wolfSSL | 15:117db924cf7c | 2837 | int ret; |
wolfSSL | 15:117db924cf7c | 2838 | |
wolfSSL | 15:117db924cf7c | 2839 | if (pRaw == NULL || pRawSz == 0 || |
wolfSSL | 15:117db924cf7c | 2840 | eRaw == NULL || eRawSz == 0 || |
wolfSSL | 15:117db924cf7c | 2841 | isPrime == NULL) { |
wolfSSL | 15:117db924cf7c | 2842 | |
wolfSSL | 15:117db924cf7c | 2843 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2844 | } |
wolfSSL | 15:117db924cf7c | 2845 | |
wolfSSL | 15:117db924cf7c | 2846 | if ((qRaw != NULL && qRawSz == 0) || (qRaw == NULL && qRawSz != 0)) |
wolfSSL | 15:117db924cf7c | 2847 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2848 | |
wolfSSL | 15:117db924cf7c | 2849 | ret = mp_init_multi(&p, &q, &e, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 2850 | |
wolfSSL | 15:117db924cf7c | 2851 | if (ret == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2852 | ret = mp_read_unsigned_bin(&p, pRaw, pRawSz); |
wolfSSL | 15:117db924cf7c | 2853 | |
wolfSSL | 15:117db924cf7c | 2854 | if (ret == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2855 | if (qRaw != NULL) { |
wolfSSL | 15:117db924cf7c | 2856 | ret = mp_read_unsigned_bin(&q, qRaw, qRawSz); |
wolfSSL | 15:117db924cf7c | 2857 | if (ret == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2858 | Q = &q; |
wolfSSL | 15:117db924cf7c | 2859 | } |
wolfSSL | 15:117db924cf7c | 2860 | } |
wolfSSL | 15:117db924cf7c | 2861 | |
wolfSSL | 15:117db924cf7c | 2862 | if (ret == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2863 | ret = mp_read_unsigned_bin(&e, eRaw, eRawSz); |
wolfSSL | 15:117db924cf7c | 2864 | |
wolfSSL | 15:117db924cf7c | 2865 | if (ret == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2866 | ret = wc_CheckProbablePrime_ex(&p, Q, &e, nlen, isPrime); |
wolfSSL | 15:117db924cf7c | 2867 | |
wolfSSL | 15:117db924cf7c | 2868 | ret = (ret == MP_OKAY) ? 0 : PRIME_GEN_E; |
wolfSSL | 15:117db924cf7c | 2869 | |
wolfSSL | 15:117db924cf7c | 2870 | mp_clear(&p); |
wolfSSL | 15:117db924cf7c | 2871 | mp_clear(&q); |
wolfSSL | 15:117db924cf7c | 2872 | mp_clear(&e); |
wolfSSL | 15:117db924cf7c | 2873 | |
wolfSSL | 15:117db924cf7c | 2874 | return ret; |
wolfSSL | 15:117db924cf7c | 2875 | } |
wolfSSL | 15:117db924cf7c | 2876 | |
wolfSSL | 15:117db924cf7c | 2877 | |
wolfSSL | 15:117db924cf7c | 2878 | /* Make an RSA key for size bits, with e specified, 65537 is a good e */ |
wolfSSL | 15:117db924cf7c | 2879 | int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 2880 | { |
wolfSSL | 15:117db924cf7c | 2881 | mp_int p, q, tmp1, tmp2, tmp3; |
wolfSSL | 15:117db924cf7c | 2882 | int err, i, failCount, primeSz, isPrime = 0; |
wolfSSL | 15:117db924cf7c | 2883 | byte* buf = NULL; |
wolfSSL | 15:117db924cf7c | 2884 | |
wolfSSL | 15:117db924cf7c | 2885 | if (key == NULL || rng == NULL) |
wolfSSL | 15:117db924cf7c | 2886 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2887 | |
wolfSSL | 15:117db924cf7c | 2888 | if (!RsaSizeCheck(size)) |
wolfSSL | 15:117db924cf7c | 2889 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2890 | |
wolfSSL | 15:117db924cf7c | 2891 | if (e < 3 || (e & 1) == 0) |
wolfSSL | 15:117db924cf7c | 2892 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 2893 | |
wolfSSL | 15:117db924cf7c | 2894 | #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA) |
wolfSSL | 15:117db924cf7c | 2895 | if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA) { |
wolfSSL | 15:117db924cf7c | 2896 | #ifdef HAVE_CAVIUM |
wolfSSL | 15:117db924cf7c | 2897 | /* TODO: Not implemented */ |
wolfSSL | 15:117db924cf7c | 2898 | #elif defined(HAVE_INTEL_QA) |
wolfSSL | 15:117db924cf7c | 2899 | /* TODO: Not implemented */ |
wolfSSL | 15:117db924cf7c | 2900 | #else |
wolfSSL | 15:117db924cf7c | 2901 | if (wc_AsyncTestInit(&key->asyncDev, ASYNC_TEST_RSA_MAKE)) { |
wolfSSL | 15:117db924cf7c | 2902 | WC_ASYNC_TEST* testDev = &key->asyncDev.test; |
wolfSSL | 15:117db924cf7c | 2903 | testDev->rsaMake.rng = rng; |
wolfSSL | 15:117db924cf7c | 2904 | testDev->rsaMake.key = key; |
wolfSSL | 15:117db924cf7c | 2905 | testDev->rsaMake.size = size; |
wolfSSL | 15:117db924cf7c | 2906 | testDev->rsaMake.e = e; |
wolfSSL | 15:117db924cf7c | 2907 | return WC_PENDING_E; |
wolfSSL | 15:117db924cf7c | 2908 | } |
wolfSSL | 15:117db924cf7c | 2909 | #endif |
wolfSSL | 15:117db924cf7c | 2910 | } |
wolfSSL | 15:117db924cf7c | 2911 | #endif |
wolfSSL | 15:117db924cf7c | 2912 | |
wolfSSL | 15:117db924cf7c | 2913 | err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL); |
wolfSSL | 15:117db924cf7c | 2914 | |
wolfSSL | 15:117db924cf7c | 2915 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2916 | err = mp_set_int(&tmp3, e); |
wolfSSL | 15:117db924cf7c | 2917 | |
wolfSSL | 15:117db924cf7c | 2918 | /* The failCount value comes from NIST FIPS 186-4, section B.3.3, |
wolfSSL | 15:117db924cf7c | 2919 | * process steps 4.7 and 5.8. */ |
wolfSSL | 15:117db924cf7c | 2920 | failCount = 5 * (size / 2); |
wolfSSL | 15:117db924cf7c | 2921 | primeSz = size / 16; /* size is the size of n in bits. |
wolfSSL | 15:117db924cf7c | 2922 | primeSz is in bytes. */ |
wolfSSL | 15:117db924cf7c | 2923 | |
wolfSSL | 15:117db924cf7c | 2924 | /* allocate buffer to work with */ |
wolfSSL | 15:117db924cf7c | 2925 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2926 | buf = (byte*)XMALLOC(primeSz, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 2927 | if (buf == NULL) |
wolfSSL | 15:117db924cf7c | 2928 | err = MEMORY_E; |
wolfSSL | 15:117db924cf7c | 2929 | } |
wolfSSL | 15:117db924cf7c | 2930 | |
wolfSSL | 15:117db924cf7c | 2931 | /* make p */ |
wolfSSL | 15:117db924cf7c | 2932 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2933 | isPrime = 0; |
wolfSSL | 15:117db924cf7c | 2934 | i = 0; |
wolfSSL | 15:117db924cf7c | 2935 | do { |
wolfSSL | 15:117db924cf7c | 2936 | #ifdef SHOW_GEN |
wolfSSL | 15:117db924cf7c | 2937 | printf("."); |
wolfSSL | 15:117db924cf7c | 2938 | fflush(stdout); |
wolfSSL | 15:117db924cf7c | 2939 | #endif |
wolfSSL | 15:117db924cf7c | 2940 | /* generate value */ |
wolfSSL | 15:117db924cf7c | 2941 | err = wc_RNG_GenerateBlock(rng, buf, primeSz); |
wolfSSL | 15:117db924cf7c | 2942 | |
wolfSSL | 15:117db924cf7c | 2943 | if (err == 0) { |
wolfSSL | 15:117db924cf7c | 2944 | /* prime lower bound has the MSB set, set it in candidate */ |
wolfSSL | 15:117db924cf7c | 2945 | buf[0] |= 0x80; |
wolfSSL | 15:117db924cf7c | 2946 | /* make candidate odd */ |
wolfSSL | 15:117db924cf7c | 2947 | buf[primeSz-1] |= 0x01; |
wolfSSL | 15:117db924cf7c | 2948 | /* load value */ |
wolfSSL | 15:117db924cf7c | 2949 | err = mp_read_unsigned_bin(&p, buf, primeSz); |
wolfSSL | 15:117db924cf7c | 2950 | } |
wolfSSL | 15:117db924cf7c | 2951 | |
wolfSSL | 15:117db924cf7c | 2952 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2953 | err = wc_CheckProbablePrime_ex(&p, NULL, &tmp3, size, &isPrime); |
wolfSSL | 15:117db924cf7c | 2954 | |
wolfSSL | 15:117db924cf7c | 2955 | #ifdef WOLFSSL_FIPS |
wolfSSL | 15:117db924cf7c | 2956 | i++; |
wolfSSL | 15:117db924cf7c | 2957 | #else |
wolfSSL | 15:117db924cf7c | 2958 | /* Keep the old retry behavior in non-FIPS build. */ |
wolfSSL | 15:117db924cf7c | 2959 | (void)i; |
wolfSSL | 15:117db924cf7c | 2960 | #endif |
wolfSSL | 15:117db924cf7c | 2961 | } while (err == MP_OKAY && !isPrime && i < failCount); |
wolfSSL | 15:117db924cf7c | 2962 | } |
wolfSSL | 15:117db924cf7c | 2963 | |
wolfSSL | 15:117db924cf7c | 2964 | if (err == MP_OKAY && !isPrime) |
wolfSSL | 15:117db924cf7c | 2965 | err = PRIME_GEN_E; |
wolfSSL | 15:117db924cf7c | 2966 | |
wolfSSL | 15:117db924cf7c | 2967 | /* make q */ |
wolfSSL | 15:117db924cf7c | 2968 | if (err == MP_OKAY) { |
wolfSSL | 15:117db924cf7c | 2969 | isPrime = 0; |
wolfSSL | 15:117db924cf7c | 2970 | i = 0; |
wolfSSL | 15:117db924cf7c | 2971 | do { |
wolfSSL | 15:117db924cf7c | 2972 | #ifdef SHOW_GEN |
wolfSSL | 15:117db924cf7c | 2973 | printf("."); |
wolfSSL | 15:117db924cf7c | 2974 | fflush(stdout); |
wolfSSL | 15:117db924cf7c | 2975 | #endif |
wolfSSL | 15:117db924cf7c | 2976 | /* generate value */ |
wolfSSL | 15:117db924cf7c | 2977 | err = wc_RNG_GenerateBlock(rng, buf, primeSz); |
wolfSSL | 15:117db924cf7c | 2978 | |
wolfSSL | 15:117db924cf7c | 2979 | if (err == 0) { |
wolfSSL | 15:117db924cf7c | 2980 | /* prime lower bound has the MSB set, set it in candidate */ |
wolfSSL | 15:117db924cf7c | 2981 | buf[0] |= 0x80; |
wolfSSL | 15:117db924cf7c | 2982 | /* make candidate odd */ |
wolfSSL | 15:117db924cf7c | 2983 | buf[primeSz-1] |= 0x01; |
wolfSSL | 15:117db924cf7c | 2984 | /* load value */ |
wolfSSL | 15:117db924cf7c | 2985 | err = mp_read_unsigned_bin(&q, buf, primeSz); |
wolfSSL | 15:117db924cf7c | 2986 | } |
wolfSSL | 15:117db924cf7c | 2987 | |
wolfSSL | 15:117db924cf7c | 2988 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 2989 | err = wc_CheckProbablePrime_ex(&p, &q, &tmp3, size, &isPrime); |
wolfSSL | 15:117db924cf7c | 2990 | |
wolfSSL | 15:117db924cf7c | 2991 | #ifdef WOLFSSL_FIPS |
wolfSSL | 15:117db924cf7c | 2992 | i++; |
wolfSSL | 15:117db924cf7c | 2993 | #else |
wolfSSL | 15:117db924cf7c | 2994 | /* Keep the old retry behavior in non-FIPS build. */ |
wolfSSL | 15:117db924cf7c | 2995 | (void)i; |
wolfSSL | 15:117db924cf7c | 2996 | #endif |
wolfSSL | 15:117db924cf7c | 2997 | } while (err == MP_OKAY && !isPrime && i < failCount); |
wolfSSL | 15:117db924cf7c | 2998 | } |
wolfSSL | 15:117db924cf7c | 2999 | |
wolfSSL | 15:117db924cf7c | 3000 | if (err == MP_OKAY && !isPrime) |
wolfSSL | 15:117db924cf7c | 3001 | err = PRIME_GEN_E; |
wolfSSL | 15:117db924cf7c | 3002 | |
wolfSSL | 15:117db924cf7c | 3003 | if (buf) { |
wolfSSL | 15:117db924cf7c | 3004 | ForceZero(buf, primeSz); |
wolfSSL | 15:117db924cf7c | 3005 | XFREE(buf, key->heap, DYNAMIC_TYPE_RSA); |
wolfSSL | 15:117db924cf7c | 3006 | } |
wolfSSL | 15:117db924cf7c | 3007 | |
wolfSSL | 15:117db924cf7c | 3008 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3009 | err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL); |
wolfSSL | 15:117db924cf7c | 3010 | |
wolfSSL | 15:117db924cf7c | 3011 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3012 | err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL); |
wolfSSL | 15:117db924cf7c | 3013 | |
wolfSSL | 15:117db924cf7c | 3014 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3015 | err = mp_sub_d(&p, 1, &tmp1); /* tmp1 = p-1 */ |
wolfSSL | 15:117db924cf7c | 3016 | |
wolfSSL | 15:117db924cf7c | 3017 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3018 | err = mp_sub_d(&q, 1, &tmp2); /* tmp2 = q-1 */ |
wolfSSL | 15:117db924cf7c | 3019 | |
wolfSSL | 15:117db924cf7c | 3020 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3021 | err = mp_lcm(&tmp1, &tmp2, &tmp3); /* tmp3 = lcm(p-1, q-1),last loop */ |
wolfSSL | 15:117db924cf7c | 3022 | |
wolfSSL | 15:117db924cf7c | 3023 | /* make key */ |
wolfSSL | 15:117db924cf7c | 3024 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3025 | err = mp_set_int(&key->e, (mp_digit)e); /* key->e = e */ |
wolfSSL | 15:117db924cf7c | 3026 | |
wolfSSL | 15:117db924cf7c | 3027 | if (err == MP_OKAY) /* key->d = 1/e mod lcm(p-1, q-1) */ |
wolfSSL | 15:117db924cf7c | 3028 | err = mp_invmod(&key->e, &tmp3, &key->d); |
wolfSSL | 15:117db924cf7c | 3029 | |
wolfSSL | 15:117db924cf7c | 3030 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3031 | err = mp_mul(&p, &q, &key->n); /* key->n = pq */ |
wolfSSL | 15:117db924cf7c | 3032 | |
wolfSSL | 15:117db924cf7c | 3033 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3034 | err = mp_mod(&key->d, &tmp1, &key->dP); /* key->dP = d mod(p-1) */ |
wolfSSL | 15:117db924cf7c | 3035 | |
wolfSSL | 15:117db924cf7c | 3036 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3037 | err = mp_mod(&key->d, &tmp2, &key->dQ); /* key->dQ = d mod(q-1) */ |
wolfSSL | 15:117db924cf7c | 3038 | |
wolfSSL | 15:117db924cf7c | 3039 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3040 | err = mp_invmod(&q, &p, &key->u); /* key->u = 1/q mod p */ |
wolfSSL | 15:117db924cf7c | 3041 | |
wolfSSL | 15:117db924cf7c | 3042 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3043 | err = mp_copy(&p, &key->p); |
wolfSSL | 15:117db924cf7c | 3044 | |
wolfSSL | 15:117db924cf7c | 3045 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3046 | err = mp_copy(&q, &key->q); |
wolfSSL | 15:117db924cf7c | 3047 | |
wolfSSL | 15:117db924cf7c | 3048 | if (err == MP_OKAY) |
wolfSSL | 15:117db924cf7c | 3049 | key->type = RSA_PRIVATE; |
wolfSSL | 15:117db924cf7c | 3050 | |
wolfSSL | 15:117db924cf7c | 3051 | mp_clear(&tmp1); |
wolfSSL | 15:117db924cf7c | 3052 | mp_clear(&tmp2); |
wolfSSL | 15:117db924cf7c | 3053 | mp_clear(&tmp3); |
wolfSSL | 15:117db924cf7c | 3054 | mp_clear(&p); |
wolfSSL | 15:117db924cf7c | 3055 | mp_clear(&q); |
wolfSSL | 15:117db924cf7c | 3056 | |
wolfSSL | 15:117db924cf7c | 3057 | /* Perform the pair-wise consistency test on the new key. */ |
wolfSSL | 15:117db924cf7c | 3058 | if (err == 0) |
wolfSSL | 15:117db924cf7c | 3059 | err = wc_CheckRsaKey(key); |
wolfSSL | 15:117db924cf7c | 3060 | |
wolfSSL | 15:117db924cf7c | 3061 | if (err != 0) { |
wolfSSL | 15:117db924cf7c | 3062 | wc_FreeRsaKey(key); |
wolfSSL | 15:117db924cf7c | 3063 | return err; |
wolfSSL | 15:117db924cf7c | 3064 | } |
wolfSSL | 15:117db924cf7c | 3065 | |
wolfSSL | 15:117db924cf7c | 3066 | #ifdef WOLFSSL_XILINX_CRYPT |
wolfSSL | 15:117db924cf7c | 3067 | if (wc_InitRsaHw(key) != 0) { |
wolfSSL | 15:117db924cf7c | 3068 | return BAD_STATE_E; |
wolfSSL | 15:117db924cf7c | 3069 | } |
wolfSSL | 15:117db924cf7c | 3070 | #endif |
wolfSSL | 15:117db924cf7c | 3071 | |
wolfSSL | 15:117db924cf7c | 3072 | return 0; |
wolfSSL | 15:117db924cf7c | 3073 | } |
wolfSSL | 15:117db924cf7c | 3074 | #endif /* WOLFSSL_KEY_GEN */ |
wolfSSL | 15:117db924cf7c | 3075 | |
wolfSSL | 15:117db924cf7c | 3076 | |
wolfSSL | 15:117db924cf7c | 3077 | #ifdef WC_RSA_BLINDING |
wolfSSL | 15:117db924cf7c | 3078 | |
wolfSSL | 15:117db924cf7c | 3079 | int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng) |
wolfSSL | 15:117db924cf7c | 3080 | { |
wolfSSL | 15:117db924cf7c | 3081 | if (key == NULL) |
wolfSSL | 15:117db924cf7c | 3082 | return BAD_FUNC_ARG; |
wolfSSL | 15:117db924cf7c | 3083 | |
wolfSSL | 15:117db924cf7c | 3084 | key->rng = rng; |
wolfSSL | 15:117db924cf7c | 3085 | |
wolfSSL | 15:117db924cf7c | 3086 | return 0; |
wolfSSL | 15:117db924cf7c | 3087 | } |
wolfSSL | 15:117db924cf7c | 3088 | |
wolfSSL | 15:117db924cf7c | 3089 | #endif /* WC_RSA_BLINDING */ |
wolfSSL | 15:117db924cf7c | 3090 | |
wolfSSL | 15:117db924cf7c | 3091 | |
wolfSSL | 15:117db924cf7c | 3092 | #undef ERROR_OUT |
wolfSSL | 15:117db924cf7c | 3093 | |
wolfSSL | 15:117db924cf7c | 3094 | #endif /* HAVE_FIPS */ |
wolfSSL | 15:117db924cf7c | 3095 | #endif /* NO_RSA */ |
wolfSSL | 15:117db924cf7c | 3096 |