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