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