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

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

Committer:
wolfSSL
Date:
Fri Jun 05 00:11:07 2020 +0000
Revision:
17:a5f916481144
Parent:
16:8e0d178b1d1e
wolfSSL 4.4.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 15:117db924cf7c 1 /* pwdbased.c
wolfSSL 15:117db924cf7c 2 *
wolfSSL 16:8e0d178b1d1e 3 * Copyright (C) 2006-2020 wolfSSL Inc.
wolfSSL 15:117db924cf7c 4 *
wolfSSL 15:117db924cf7c 5 * This file is part of wolfSSL.
wolfSSL 15:117db924cf7c 6 *
wolfSSL 15:117db924cf7c 7 * wolfSSL is free software; you can redistribute it and/or modify
wolfSSL 15:117db924cf7c 8 * it under the terms of the GNU General Public License as published by
wolfSSL 15:117db924cf7c 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 15:117db924cf7c 10 * (at your option) any later version.
wolfSSL 15:117db924cf7c 11 *
wolfSSL 15:117db924cf7c 12 * wolfSSL is distributed in the hope that it will be useful,
wolfSSL 15:117db924cf7c 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 15:117db924cf7c 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 15:117db924cf7c 15 * GNU General Public License for more details.
wolfSSL 15:117db924cf7c 16 *
wolfSSL 15:117db924cf7c 17 * You should have received a copy of the GNU General Public License
wolfSSL 15:117db924cf7c 18 * along with this program; if not, write to the Free Software
wolfSSL 15:117db924cf7c 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
wolfSSL 15:117db924cf7c 20 */
wolfSSL 15:117db924cf7c 21
wolfSSL 15:117db924cf7c 22
wolfSSL 15:117db924cf7c 23 #ifdef HAVE_CONFIG_H
wolfSSL 15:117db924cf7c 24 #include <config.h>
wolfSSL 15:117db924cf7c 25 #endif
wolfSSL 15:117db924cf7c 26
wolfSSL 15:117db924cf7c 27 #include <wolfssl/wolfcrypt/settings.h>
wolfSSL 15:117db924cf7c 28
wolfSSL 15:117db924cf7c 29 #ifndef NO_PWDBASED
wolfSSL 15:117db924cf7c 30
wolfSSL 15:117db924cf7c 31 #include <wolfssl/wolfcrypt/pwdbased.h>
wolfSSL 15:117db924cf7c 32 #include <wolfssl/wolfcrypt/hmac.h>
wolfSSL 15:117db924cf7c 33 #include <wolfssl/wolfcrypt/hash.h>
wolfSSL 15:117db924cf7c 34 #include <wolfssl/wolfcrypt/integer.h>
wolfSSL 15:117db924cf7c 35 #include <wolfssl/wolfcrypt/error-crypt.h>
wolfSSL 15:117db924cf7c 36
wolfSSL 15:117db924cf7c 37 #ifdef NO_INLINE
wolfSSL 15:117db924cf7c 38 #include <wolfssl/wolfcrypt/misc.h>
wolfSSL 15:117db924cf7c 39 #else
wolfSSL 15:117db924cf7c 40 #define WOLFSSL_MISC_INCLUDED
wolfSSL 15:117db924cf7c 41 #include <wolfcrypt/src/misc.c>
wolfSSL 15:117db924cf7c 42 #endif
wolfSSL 15:117db924cf7c 43
wolfSSL 15:117db924cf7c 44
wolfSSL 16:8e0d178b1d1e 45 #ifdef HAVE_PBKDF1
wolfSSL 16:8e0d178b1d1e 46
wolfSSL 15:117db924cf7c 47 /* PKCS#5 v1.5 with non standard extension to optionally derive the extra data (IV) */
wolfSSL 15:117db924cf7c 48 int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
wolfSSL 15:117db924cf7c 49 const byte* passwd, int passwdLen, const byte* salt, int saltLen,
wolfSSL 15:117db924cf7c 50 int iterations, int hashType, void* heap)
wolfSSL 15:117db924cf7c 51 {
wolfSSL 15:117db924cf7c 52 int err;
wolfSSL 15:117db924cf7c 53 int keyLeft, ivLeft, i;
wolfSSL 15:117db924cf7c 54 int digestLeft, store;
wolfSSL 15:117db924cf7c 55 int keyOutput = 0;
wolfSSL 15:117db924cf7c 56 int diestLen;
wolfSSL 15:117db924cf7c 57 byte digest[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 58 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 59 wc_HashAlg* hash = NULL;
wolfSSL 15:117db924cf7c 60 #else
wolfSSL 15:117db924cf7c 61 wc_HashAlg hash[1];
wolfSSL 15:117db924cf7c 62 #endif
wolfSSL 15:117db924cf7c 63 enum wc_HashType hashT;
wolfSSL 15:117db924cf7c 64
wolfSSL 15:117db924cf7c 65 (void)heap;
wolfSSL 15:117db924cf7c 66
wolfSSL 15:117db924cf7c 67 if (key == NULL || keyLen < 0 || passwdLen < 0 || saltLen < 0 || ivLen < 0){
wolfSSL 15:117db924cf7c 68 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 69 }
wolfSSL 15:117db924cf7c 70
wolfSSL 15:117db924cf7c 71 if (iterations <= 0)
wolfSSL 15:117db924cf7c 72 iterations = 1;
wolfSSL 15:117db924cf7c 73
wolfSSL 15:117db924cf7c 74 hashT = wc_HashTypeConvert(hashType);
wolfSSL 15:117db924cf7c 75 err = wc_HashGetDigestSize(hashT);
wolfSSL 15:117db924cf7c 76 if (err < 0)
wolfSSL 15:117db924cf7c 77 return err;
wolfSSL 15:117db924cf7c 78 diestLen = err;
wolfSSL 15:117db924cf7c 79
wolfSSL 15:117db924cf7c 80 /* initialize hash */
wolfSSL 15:117db924cf7c 81 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 82 hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), heap,
wolfSSL 15:117db924cf7c 83 DYNAMIC_TYPE_HASHCTX);
wolfSSL 15:117db924cf7c 84 if (hash == NULL)
wolfSSL 15:117db924cf7c 85 return MEMORY_E;
wolfSSL 15:117db924cf7c 86 #endif
wolfSSL 15:117db924cf7c 87
wolfSSL 16:8e0d178b1d1e 88 err = wc_HashInit_ex(hash, hashT, heap, INVALID_DEVID);
wolfSSL 15:117db924cf7c 89 if (err != 0) {
wolfSSL 15:117db924cf7c 90 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 91 XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
wolfSSL 15:117db924cf7c 92 #endif
wolfSSL 15:117db924cf7c 93 return err;
wolfSSL 15:117db924cf7c 94 }
wolfSSL 15:117db924cf7c 95
wolfSSL 15:117db924cf7c 96 keyLeft = keyLen;
wolfSSL 15:117db924cf7c 97 ivLeft = ivLen;
wolfSSL 15:117db924cf7c 98 while (keyOutput < (keyLen + ivLen)) {
wolfSSL 15:117db924cf7c 99 digestLeft = diestLen;
wolfSSL 15:117db924cf7c 100 /* D_(i - 1) */
wolfSSL 15:117db924cf7c 101 if (keyOutput) { /* first time D_0 is empty */
wolfSSL 15:117db924cf7c 102 err = wc_HashUpdate(hash, hashT, digest, diestLen);
wolfSSL 15:117db924cf7c 103 if (err != 0) break;
wolfSSL 15:117db924cf7c 104 }
wolfSSL 15:117db924cf7c 105
wolfSSL 15:117db924cf7c 106 /* data */
wolfSSL 15:117db924cf7c 107 err = wc_HashUpdate(hash, hashT, passwd, passwdLen);
wolfSSL 15:117db924cf7c 108 if (err != 0) break;
wolfSSL 15:117db924cf7c 109
wolfSSL 15:117db924cf7c 110 /* salt */
wolfSSL 15:117db924cf7c 111 if (salt) {
wolfSSL 15:117db924cf7c 112 err = wc_HashUpdate(hash, hashT, salt, saltLen);
wolfSSL 15:117db924cf7c 113 if (err != 0) break;
wolfSSL 15:117db924cf7c 114 }
wolfSSL 15:117db924cf7c 115
wolfSSL 15:117db924cf7c 116 err = wc_HashFinal(hash, hashT, digest);
wolfSSL 15:117db924cf7c 117 if (err != 0) break;
wolfSSL 15:117db924cf7c 118
wolfSSL 15:117db924cf7c 119 /* count */
wolfSSL 15:117db924cf7c 120 for (i = 1; i < iterations; i++) {
wolfSSL 15:117db924cf7c 121 err = wc_HashUpdate(hash, hashT, digest, diestLen);
wolfSSL 15:117db924cf7c 122 if (err != 0) break;
wolfSSL 15:117db924cf7c 123
wolfSSL 15:117db924cf7c 124 err = wc_HashFinal(hash, hashT, digest);
wolfSSL 15:117db924cf7c 125 if (err != 0) break;
wolfSSL 15:117db924cf7c 126 }
wolfSSL 15:117db924cf7c 127
wolfSSL 15:117db924cf7c 128 if (keyLeft) {
wolfSSL 15:117db924cf7c 129 store = min(keyLeft, diestLen);
wolfSSL 15:117db924cf7c 130 XMEMCPY(&key[keyLen - keyLeft], digest, store);
wolfSSL 15:117db924cf7c 131
wolfSSL 15:117db924cf7c 132 keyOutput += store;
wolfSSL 15:117db924cf7c 133 keyLeft -= store;
wolfSSL 15:117db924cf7c 134 digestLeft -= store;
wolfSSL 15:117db924cf7c 135 }
wolfSSL 15:117db924cf7c 136
wolfSSL 15:117db924cf7c 137 if (ivLeft && digestLeft) {
wolfSSL 15:117db924cf7c 138 store = min(ivLeft, digestLeft);
wolfSSL 15:117db924cf7c 139 if (iv != NULL)
wolfSSL 15:117db924cf7c 140 XMEMCPY(&iv[ivLen - ivLeft],
wolfSSL 15:117db924cf7c 141 &digest[diestLen - digestLeft], store);
wolfSSL 15:117db924cf7c 142 keyOutput += store;
wolfSSL 15:117db924cf7c 143 ivLeft -= store;
wolfSSL 15:117db924cf7c 144 }
wolfSSL 15:117db924cf7c 145 }
wolfSSL 15:117db924cf7c 146
wolfSSL 16:8e0d178b1d1e 147 wc_HashFree(hash, hashT);
wolfSSL 16:8e0d178b1d1e 148
wolfSSL 15:117db924cf7c 149 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 150 XFREE(hash, heap, DYNAMIC_TYPE_HASHCTX);
wolfSSL 15:117db924cf7c 151 #endif
wolfSSL 15:117db924cf7c 152
wolfSSL 15:117db924cf7c 153 if (err != 0)
wolfSSL 15:117db924cf7c 154 return err;
wolfSSL 15:117db924cf7c 155
wolfSSL 15:117db924cf7c 156 if (keyOutput != (keyLen + ivLen))
wolfSSL 15:117db924cf7c 157 return BUFFER_E;
wolfSSL 15:117db924cf7c 158
wolfSSL 15:117db924cf7c 159 return err;
wolfSSL 15:117db924cf7c 160 }
wolfSSL 15:117db924cf7c 161
wolfSSL 15:117db924cf7c 162 /* PKCS#5 v1.5 */
wolfSSL 15:117db924cf7c 163 int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
wolfSSL 15:117db924cf7c 164 int sLen, int iterations, int kLen, int hashType)
wolfSSL 15:117db924cf7c 165 {
wolfSSL 15:117db924cf7c 166 return wc_PBKDF1_ex(output, kLen, NULL, 0,
wolfSSL 15:117db924cf7c 167 passwd, pLen, salt, sLen, iterations, hashType, NULL);
wolfSSL 15:117db924cf7c 168 }
wolfSSL 15:117db924cf7c 169
wolfSSL 16:8e0d178b1d1e 170 #endif /* HAVE_PKCS5 */
wolfSSL 15:117db924cf7c 171
wolfSSL 16:8e0d178b1d1e 172 #ifdef HAVE_PBKDF2
wolfSSL 16:8e0d178b1d1e 173
wolfSSL 16:8e0d178b1d1e 174 int wc_PBKDF2_ex(byte* output, const byte* passwd, int pLen, const byte* salt,
wolfSSL 16:8e0d178b1d1e 175 int sLen, int iterations, int kLen, int hashType, void* heap, int devId)
wolfSSL 15:117db924cf7c 176 {
wolfSSL 15:117db924cf7c 177 word32 i = 1;
wolfSSL 15:117db924cf7c 178 int hLen;
wolfSSL 15:117db924cf7c 179 int j, ret;
wolfSSL 15:117db924cf7c 180 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 181 byte* buffer;
wolfSSL 15:117db924cf7c 182 Hmac* hmac;
wolfSSL 15:117db924cf7c 183 #else
wolfSSL 15:117db924cf7c 184 byte buffer[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 185 Hmac hmac[1];
wolfSSL 15:117db924cf7c 186 #endif
wolfSSL 15:117db924cf7c 187 enum wc_HashType hashT;
wolfSSL 15:117db924cf7c 188
wolfSSL 15:117db924cf7c 189 if (output == NULL || pLen < 0 || sLen < 0 || kLen < 0) {
wolfSSL 15:117db924cf7c 190 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 191 }
wolfSSL 15:117db924cf7c 192
wolfSSL 15:117db924cf7c 193 if (iterations <= 0)
wolfSSL 15:117db924cf7c 194 iterations = 1;
wolfSSL 15:117db924cf7c 195
wolfSSL 15:117db924cf7c 196 hashT = wc_HashTypeConvert(hashType);
wolfSSL 15:117db924cf7c 197 hLen = wc_HashGetDigestSize(hashT);
wolfSSL 15:117db924cf7c 198 if (hLen < 0)
wolfSSL 15:117db924cf7c 199 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 200
wolfSSL 15:117db924cf7c 201 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 202 buffer = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 203 if (buffer == NULL)
wolfSSL 15:117db924cf7c 204 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 205 hmac = (Hmac*)XMALLOC(sizeof(Hmac), heap, DYNAMIC_TYPE_HMAC);
wolfSSL 16:8e0d178b1d1e 206 if (hmac == NULL) {
wolfSSL 16:8e0d178b1d1e 207 XFREE(buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 208 return MEMORY_E;
wolfSSL 16:8e0d178b1d1e 209 }
wolfSSL 15:117db924cf7c 210 #endif
wolfSSL 15:117db924cf7c 211
wolfSSL 16:8e0d178b1d1e 212 ret = wc_HmacInit(hmac, heap, devId);
wolfSSL 15:117db924cf7c 213 if (ret == 0) {
wolfSSL 15:117db924cf7c 214 /* use int hashType here, since HMAC FIPS uses the old unique value */
wolfSSL 15:117db924cf7c 215 ret = wc_HmacSetKey(hmac, hashType, passwd, pLen);
wolfSSL 15:117db924cf7c 216
wolfSSL 15:117db924cf7c 217 while (ret == 0 && kLen) {
wolfSSL 15:117db924cf7c 218 int currentLen;
wolfSSL 15:117db924cf7c 219
wolfSSL 15:117db924cf7c 220 ret = wc_HmacUpdate(hmac, salt, sLen);
wolfSSL 15:117db924cf7c 221 if (ret != 0)
wolfSSL 15:117db924cf7c 222 break;
wolfSSL 15:117db924cf7c 223
wolfSSL 15:117db924cf7c 224 /* encode i */
wolfSSL 15:117db924cf7c 225 for (j = 0; j < 4; j++) {
wolfSSL 15:117db924cf7c 226 byte b = (byte)(i >> ((3-j) * 8));
wolfSSL 15:117db924cf7c 227
wolfSSL 15:117db924cf7c 228 ret = wc_HmacUpdate(hmac, &b, 1);
wolfSSL 15:117db924cf7c 229 if (ret != 0)
wolfSSL 15:117db924cf7c 230 break;
wolfSSL 15:117db924cf7c 231 }
wolfSSL 15:117db924cf7c 232
wolfSSL 15:117db924cf7c 233 /* check ret from inside for loop */
wolfSSL 15:117db924cf7c 234 if (ret != 0)
wolfSSL 15:117db924cf7c 235 break;
wolfSSL 15:117db924cf7c 236
wolfSSL 15:117db924cf7c 237 ret = wc_HmacFinal(hmac, buffer);
wolfSSL 15:117db924cf7c 238 if (ret != 0)
wolfSSL 15:117db924cf7c 239 break;
wolfSSL 15:117db924cf7c 240
wolfSSL 15:117db924cf7c 241 currentLen = min(kLen, hLen);
wolfSSL 15:117db924cf7c 242 XMEMCPY(output, buffer, currentLen);
wolfSSL 15:117db924cf7c 243
wolfSSL 15:117db924cf7c 244 for (j = 1; j < iterations; j++) {
wolfSSL 15:117db924cf7c 245 ret = wc_HmacUpdate(hmac, buffer, hLen);
wolfSSL 15:117db924cf7c 246 if (ret != 0)
wolfSSL 15:117db924cf7c 247 break;
wolfSSL 15:117db924cf7c 248 ret = wc_HmacFinal(hmac, buffer);
wolfSSL 15:117db924cf7c 249 if (ret != 0)
wolfSSL 15:117db924cf7c 250 break;
wolfSSL 15:117db924cf7c 251 xorbuf(output, buffer, currentLen);
wolfSSL 15:117db924cf7c 252 }
wolfSSL 15:117db924cf7c 253
wolfSSL 15:117db924cf7c 254 /* check ret from inside for loop */
wolfSSL 15:117db924cf7c 255 if (ret != 0)
wolfSSL 15:117db924cf7c 256 break;
wolfSSL 15:117db924cf7c 257
wolfSSL 15:117db924cf7c 258 output += currentLen;
wolfSSL 15:117db924cf7c 259 kLen -= currentLen;
wolfSSL 15:117db924cf7c 260 i++;
wolfSSL 15:117db924cf7c 261 }
wolfSSL 15:117db924cf7c 262 wc_HmacFree(hmac);
wolfSSL 15:117db924cf7c 263 }
wolfSSL 15:117db924cf7c 264
wolfSSL 15:117db924cf7c 265 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 16:8e0d178b1d1e 266 XFREE(buffer, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 16:8e0d178b1d1e 267 XFREE(hmac, heap, DYNAMIC_TYPE_HMAC);
wolfSSL 15:117db924cf7c 268 #endif
wolfSSL 15:117db924cf7c 269
wolfSSL 15:117db924cf7c 270 return ret;
wolfSSL 15:117db924cf7c 271 }
wolfSSL 15:117db924cf7c 272
wolfSSL 16:8e0d178b1d1e 273 int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
wolfSSL 16:8e0d178b1d1e 274 int sLen, int iterations, int kLen, int hashType)
wolfSSL 16:8e0d178b1d1e 275 {
wolfSSL 16:8e0d178b1d1e 276 return wc_PBKDF2_ex(output, passwd, pLen, salt, sLen, iterations, kLen,
wolfSSL 16:8e0d178b1d1e 277 hashType, NULL, INVALID_DEVID);
wolfSSL 16:8e0d178b1d1e 278 }
wolfSSL 16:8e0d178b1d1e 279
wolfSSL 16:8e0d178b1d1e 280 #endif /* HAVE_PBKDF2 */
wolfSSL 16:8e0d178b1d1e 281
wolfSSL 16:8e0d178b1d1e 282 #ifdef HAVE_PKCS12
wolfSSL 16:8e0d178b1d1e 283
wolfSSL 15:117db924cf7c 284 /* helper for PKCS12_PBKDF(), does hash operation */
wolfSSL 15:117db924cf7c 285 static int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
wolfSSL 15:117db924cf7c 286 byte* Ai, word32 u, int iterations)
wolfSSL 15:117db924cf7c 287 {
wolfSSL 15:117db924cf7c 288 int i;
wolfSSL 15:117db924cf7c 289 int ret = 0;
wolfSSL 15:117db924cf7c 290 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 291 wc_HashAlg* hash = NULL;
wolfSSL 15:117db924cf7c 292 #else
wolfSSL 15:117db924cf7c 293 wc_HashAlg hash[1];
wolfSSL 15:117db924cf7c 294 #endif
wolfSSL 15:117db924cf7c 295 enum wc_HashType hashT;
wolfSSL 15:117db924cf7c 296
wolfSSL 15:117db924cf7c 297 if (buffer == NULL || Ai == NULL) {
wolfSSL 15:117db924cf7c 298 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 299 }
wolfSSL 15:117db924cf7c 300
wolfSSL 15:117db924cf7c 301 hashT = wc_HashTypeConvert(hashType);
wolfSSL 15:117db924cf7c 302
wolfSSL 15:117db924cf7c 303 /* initialize hash */
wolfSSL 15:117db924cf7c 304 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 305 hash = (wc_HashAlg*)XMALLOC(sizeof(wc_HashAlg), NULL,
wolfSSL 15:117db924cf7c 306 DYNAMIC_TYPE_HASHCTX);
wolfSSL 15:117db924cf7c 307 if (hash == NULL)
wolfSSL 15:117db924cf7c 308 return MEMORY_E;
wolfSSL 15:117db924cf7c 309 #endif
wolfSSL 15:117db924cf7c 310
wolfSSL 15:117db924cf7c 311 ret = wc_HashInit(hash, hashT);
wolfSSL 15:117db924cf7c 312 if (ret != 0) {
wolfSSL 15:117db924cf7c 313 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 314 XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
wolfSSL 15:117db924cf7c 315 #endif
wolfSSL 15:117db924cf7c 316 return ret;
wolfSSL 15:117db924cf7c 317 }
wolfSSL 15:117db924cf7c 318
wolfSSL 15:117db924cf7c 319 ret = wc_HashUpdate(hash, hashT, buffer, totalLen);
wolfSSL 15:117db924cf7c 320
wolfSSL 15:117db924cf7c 321 if (ret == 0)
wolfSSL 15:117db924cf7c 322 ret = wc_HashFinal(hash, hashT, Ai);
wolfSSL 15:117db924cf7c 323
wolfSSL 15:117db924cf7c 324 for (i = 1; i < iterations; i++) {
wolfSSL 15:117db924cf7c 325 if (ret == 0)
wolfSSL 15:117db924cf7c 326 ret = wc_HashUpdate(hash, hashT, Ai, u);
wolfSSL 15:117db924cf7c 327 if (ret == 0)
wolfSSL 15:117db924cf7c 328 ret = wc_HashFinal(hash, hashT, Ai);
wolfSSL 15:117db924cf7c 329 }
wolfSSL 15:117db924cf7c 330
wolfSSL 16:8e0d178b1d1e 331 wc_HashFree(hash, hashT);
wolfSSL 16:8e0d178b1d1e 332
wolfSSL 15:117db924cf7c 333 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 334 XFREE(hash, NULL, DYNAMIC_TYPE_HASHCTX);
wolfSSL 15:117db924cf7c 335 #endif
wolfSSL 15:117db924cf7c 336
wolfSSL 15:117db924cf7c 337 return ret;
wolfSSL 15:117db924cf7c 338 }
wolfSSL 15:117db924cf7c 339
wolfSSL 15:117db924cf7c 340
wolfSSL 15:117db924cf7c 341 int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,
wolfSSL 15:117db924cf7c 342 const byte* salt, int saltLen, int iterations, int kLen, int hashType,
wolfSSL 15:117db924cf7c 343 int id)
wolfSSL 15:117db924cf7c 344 {
wolfSSL 15:117db924cf7c 345 return wc_PKCS12_PBKDF_ex(output, passwd, passLen, salt, saltLen,
wolfSSL 15:117db924cf7c 346 iterations, kLen, hashType, id, NULL);
wolfSSL 15:117db924cf7c 347 }
wolfSSL 15:117db924cf7c 348
wolfSSL 15:117db924cf7c 349
wolfSSL 15:117db924cf7c 350 /* extended API that allows a heap hint to be used */
wolfSSL 15:117db924cf7c 351 int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
wolfSSL 15:117db924cf7c 352 const byte* salt, int saltLen, int iterations, int kLen,
wolfSSL 15:117db924cf7c 353 int hashType, int id, void* heap)
wolfSSL 15:117db924cf7c 354 {
wolfSSL 15:117db924cf7c 355 /* all in bytes instead of bits */
wolfSSL 15:117db924cf7c 356 word32 u, v, dLen, pLen, iLen, sLen, totalLen;
wolfSSL 15:117db924cf7c 357 int dynamic = 0;
wolfSSL 15:117db924cf7c 358 int ret = 0;
wolfSSL 15:117db924cf7c 359 int i;
wolfSSL 15:117db924cf7c 360 byte *D, *S, *P, *I;
wolfSSL 15:117db924cf7c 361 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 362 byte staticBuffer[1]; /* force dynamic usage */
wolfSSL 15:117db924cf7c 363 #else
wolfSSL 15:117db924cf7c 364 byte staticBuffer[1024];
wolfSSL 15:117db924cf7c 365 #endif
wolfSSL 15:117db924cf7c 366 byte* buffer = staticBuffer;
wolfSSL 15:117db924cf7c 367
wolfSSL 15:117db924cf7c 368 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 369 byte* Ai;
wolfSSL 15:117db924cf7c 370 byte* B;
wolfSSL 15:117db924cf7c 371 #else
wolfSSL 15:117db924cf7c 372 byte Ai[WC_MAX_DIGEST_SIZE];
wolfSSL 15:117db924cf7c 373 byte B[WC_MAX_BLOCK_SIZE];
wolfSSL 15:117db924cf7c 374 #endif
wolfSSL 15:117db924cf7c 375 enum wc_HashType hashT;
wolfSSL 15:117db924cf7c 376
wolfSSL 15:117db924cf7c 377 (void)heap;
wolfSSL 15:117db924cf7c 378
wolfSSL 15:117db924cf7c 379 if (output == NULL || passLen < 0 || saltLen < 0 || kLen < 0) {
wolfSSL 15:117db924cf7c 380 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 381 }
wolfSSL 15:117db924cf7c 382
wolfSSL 15:117db924cf7c 383 if (iterations <= 0)
wolfSSL 15:117db924cf7c 384 iterations = 1;
wolfSSL 15:117db924cf7c 385
wolfSSL 15:117db924cf7c 386 hashT = wc_HashTypeConvert(hashType);
wolfSSL 15:117db924cf7c 387 ret = wc_HashGetDigestSize(hashT);
wolfSSL 15:117db924cf7c 388 if (ret < 0)
wolfSSL 15:117db924cf7c 389 return ret;
wolfSSL 15:117db924cf7c 390 u = ret;
wolfSSL 15:117db924cf7c 391
wolfSSL 15:117db924cf7c 392 ret = wc_HashGetBlockSize(hashT);
wolfSSL 15:117db924cf7c 393 if (ret < 0)
wolfSSL 15:117db924cf7c 394 return ret;
wolfSSL 15:117db924cf7c 395 v = ret;
wolfSSL 15:117db924cf7c 396
wolfSSL 15:117db924cf7c 397 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 398 Ai = (byte*)XMALLOC(WC_MAX_DIGEST_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 399 if (Ai == NULL)
wolfSSL 15:117db924cf7c 400 return MEMORY_E;
wolfSSL 15:117db924cf7c 401
wolfSSL 15:117db924cf7c 402 B = (byte*)XMALLOC(WC_MAX_BLOCK_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 403 if (B == NULL) {
wolfSSL 15:117db924cf7c 404 XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 405 return MEMORY_E;
wolfSSL 15:117db924cf7c 406 }
wolfSSL 15:117db924cf7c 407 #endif
wolfSSL 15:117db924cf7c 408
wolfSSL 15:117db924cf7c 409 XMEMSET(Ai, 0, WC_MAX_DIGEST_SIZE);
wolfSSL 15:117db924cf7c 410 XMEMSET(B, 0, WC_MAX_BLOCK_SIZE);
wolfSSL 15:117db924cf7c 411
wolfSSL 15:117db924cf7c 412 dLen = v;
wolfSSL 15:117db924cf7c 413 sLen = v * ((saltLen + v - 1) / v);
wolfSSL 15:117db924cf7c 414 if (passLen)
wolfSSL 15:117db924cf7c 415 pLen = v * ((passLen + v - 1) / v);
wolfSSL 15:117db924cf7c 416 else
wolfSSL 15:117db924cf7c 417 pLen = 0;
wolfSSL 15:117db924cf7c 418 iLen = sLen + pLen;
wolfSSL 15:117db924cf7c 419
wolfSSL 15:117db924cf7c 420 totalLen = dLen + sLen + pLen;
wolfSSL 15:117db924cf7c 421
wolfSSL 15:117db924cf7c 422 if (totalLen > sizeof(staticBuffer)) {
wolfSSL 15:117db924cf7c 423 buffer = (byte*)XMALLOC(totalLen, heap, DYNAMIC_TYPE_KEY);
wolfSSL 15:117db924cf7c 424 if (buffer == NULL) {
wolfSSL 15:117db924cf7c 425 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 426 XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 427 XFREE(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 428 #endif
wolfSSL 15:117db924cf7c 429 return MEMORY_E;
wolfSSL 15:117db924cf7c 430 }
wolfSSL 15:117db924cf7c 431 dynamic = 1;
wolfSSL 15:117db924cf7c 432 }
wolfSSL 15:117db924cf7c 433
wolfSSL 15:117db924cf7c 434 D = buffer;
wolfSSL 15:117db924cf7c 435 S = D + dLen;
wolfSSL 15:117db924cf7c 436 P = S + sLen;
wolfSSL 15:117db924cf7c 437 I = S;
wolfSSL 15:117db924cf7c 438
wolfSSL 15:117db924cf7c 439 XMEMSET(D, id, dLen);
wolfSSL 15:117db924cf7c 440
wolfSSL 15:117db924cf7c 441 for (i = 0; i < (int)sLen; i++)
wolfSSL 15:117db924cf7c 442 S[i] = salt[i % saltLen];
wolfSSL 15:117db924cf7c 443 for (i = 0; i < (int)pLen; i++)
wolfSSL 15:117db924cf7c 444 P[i] = passwd[i % passLen];
wolfSSL 15:117db924cf7c 445
wolfSSL 15:117db924cf7c 446 while (kLen > 0) {
wolfSSL 15:117db924cf7c 447 word32 currentLen;
wolfSSL 15:117db924cf7c 448 mp_int B1;
wolfSSL 15:117db924cf7c 449
wolfSSL 15:117db924cf7c 450 ret = DoPKCS12Hash(hashType, buffer, totalLen, Ai, u, iterations);
wolfSSL 15:117db924cf7c 451 if (ret < 0)
wolfSSL 15:117db924cf7c 452 break;
wolfSSL 15:117db924cf7c 453
wolfSSL 15:117db924cf7c 454 for (i = 0; i < (int)v; i++)
wolfSSL 15:117db924cf7c 455 B[i] = Ai[i % u];
wolfSSL 15:117db924cf7c 456
wolfSSL 15:117db924cf7c 457 if (mp_init(&B1) != MP_OKAY)
wolfSSL 15:117db924cf7c 458 ret = MP_INIT_E;
wolfSSL 15:117db924cf7c 459 else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)
wolfSSL 15:117db924cf7c 460 ret = MP_READ_E;
wolfSSL 15:117db924cf7c 461 else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY)
wolfSSL 15:117db924cf7c 462 ret = MP_ADD_E;
wolfSSL 15:117db924cf7c 463
wolfSSL 15:117db924cf7c 464 if (ret != 0) {
wolfSSL 15:117db924cf7c 465 mp_clear(&B1);
wolfSSL 15:117db924cf7c 466 break;
wolfSSL 15:117db924cf7c 467 }
wolfSSL 15:117db924cf7c 468
wolfSSL 15:117db924cf7c 469 for (i = 0; i < (int)iLen; i += v) {
wolfSSL 15:117db924cf7c 470 int outSz;
wolfSSL 15:117db924cf7c 471 mp_int i1;
wolfSSL 15:117db924cf7c 472 mp_int res;
wolfSSL 15:117db924cf7c 473
wolfSSL 15:117db924cf7c 474 if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) {
wolfSSL 15:117db924cf7c 475 ret = MP_INIT_E;
wolfSSL 15:117db924cf7c 476 break;
wolfSSL 15:117db924cf7c 477 }
wolfSSL 15:117db924cf7c 478 if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)
wolfSSL 15:117db924cf7c 479 ret = MP_READ_E;
wolfSSL 15:117db924cf7c 480 else if (mp_add(&i1, &B1, &res) != MP_OKAY)
wolfSSL 15:117db924cf7c 481 ret = MP_ADD_E;
wolfSSL 15:117db924cf7c 482 else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)
wolfSSL 15:117db924cf7c 483 ret = MP_TO_E;
wolfSSL 15:117db924cf7c 484 else {
wolfSSL 15:117db924cf7c 485 if (outSz > (int)v) {
wolfSSL 15:117db924cf7c 486 /* take off MSB */
wolfSSL 16:8e0d178b1d1e 487 byte tmp[WC_MAX_BLOCK_SIZE + 1];
wolfSSL 15:117db924cf7c 488 ret = mp_to_unsigned_bin(&res, tmp);
wolfSSL 15:117db924cf7c 489 XMEMCPY(I + i, tmp + 1, v);
wolfSSL 15:117db924cf7c 490 }
wolfSSL 15:117db924cf7c 491 else if (outSz < (int)v) {
wolfSSL 15:117db924cf7c 492 XMEMSET(I + i, 0, v - outSz);
wolfSSL 15:117db924cf7c 493 ret = mp_to_unsigned_bin(&res, I + i + v - outSz);
wolfSSL 15:117db924cf7c 494 }
wolfSSL 15:117db924cf7c 495 else
wolfSSL 15:117db924cf7c 496 ret = mp_to_unsigned_bin(&res, I + i);
wolfSSL 15:117db924cf7c 497 }
wolfSSL 15:117db924cf7c 498
wolfSSL 15:117db924cf7c 499 mp_clear(&i1);
wolfSSL 15:117db924cf7c 500 mp_clear(&res);
wolfSSL 15:117db924cf7c 501 if (ret < 0) break;
wolfSSL 15:117db924cf7c 502 }
wolfSSL 15:117db924cf7c 503
wolfSSL 15:117db924cf7c 504 currentLen = min(kLen, (int)u);
wolfSSL 15:117db924cf7c 505 XMEMCPY(output, Ai, currentLen);
wolfSSL 15:117db924cf7c 506 output += currentLen;
wolfSSL 15:117db924cf7c 507 kLen -= currentLen;
wolfSSL 15:117db924cf7c 508 mp_clear(&B1);
wolfSSL 15:117db924cf7c 509 }
wolfSSL 15:117db924cf7c 510
wolfSSL 15:117db924cf7c 511 if (dynamic) XFREE(buffer, heap, DYNAMIC_TYPE_KEY);
wolfSSL 15:117db924cf7c 512
wolfSSL 15:117db924cf7c 513 #ifdef WOLFSSL_SMALL_STACK
wolfSSL 15:117db924cf7c 514 XFREE(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 515 XFREE(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 516 #endif
wolfSSL 15:117db924cf7c 517
wolfSSL 15:117db924cf7c 518 return ret;
wolfSSL 15:117db924cf7c 519 }
wolfSSL 15:117db924cf7c 520
wolfSSL 16:8e0d178b1d1e 521 #endif /* HAVE_PKCS12 */
wolfSSL 16:8e0d178b1d1e 522
wolfSSL 15:117db924cf7c 523 #ifdef HAVE_SCRYPT
wolfSSL 15:117db924cf7c 524 /* Rotate the 32-bit value a by b bits to the left.
wolfSSL 15:117db924cf7c 525 *
wolfSSL 15:117db924cf7c 526 * a 32-bit value.
wolfSSL 15:117db924cf7c 527 * b Number of bits to rotate.
wolfSSL 15:117db924cf7c 528 * returns rotated value.
wolfSSL 15:117db924cf7c 529 */
wolfSSL 15:117db924cf7c 530 #define R(a, b) rotlFixed(a, b)
wolfSSL 15:117db924cf7c 531
wolfSSL 15:117db924cf7c 532 /* One round of Salsa20/8.
wolfSSL 15:117db924cf7c 533 * Code taken from RFC 7914: scrypt PBKDF.
wolfSSL 15:117db924cf7c 534 *
wolfSSL 15:117db924cf7c 535 * out Output buffer.
wolfSSL 15:117db924cf7c 536 * in Input data to hash.
wolfSSL 15:117db924cf7c 537 */
wolfSSL 15:117db924cf7c 538 static void scryptSalsa(word32* out, word32* in)
wolfSSL 15:117db924cf7c 539 {
wolfSSL 15:117db924cf7c 540 int i;
wolfSSL 15:117db924cf7c 541 word32 x[16];
wolfSSL 15:117db924cf7c 542
wolfSSL 15:117db924cf7c 543 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 15:117db924cf7c 544 for (i = 0; i < 16; ++i)
wolfSSL 15:117db924cf7c 545 x[i] = in[i];
wolfSSL 15:117db924cf7c 546 #else
wolfSSL 15:117db924cf7c 547 for (i = 0; i < 16; i++)
wolfSSL 15:117db924cf7c 548 x[i] = ByteReverseWord32(in[i]);
wolfSSL 15:117db924cf7c 549 #endif
wolfSSL 15:117db924cf7c 550 for (i = 8; i > 0; i -= 2) {
wolfSSL 15:117db924cf7c 551 x[ 4] ^= R(x[ 0] + x[12], 7); x[ 8] ^= R(x[ 4] + x[ 0], 9);
wolfSSL 15:117db924cf7c 552 x[12] ^= R(x[ 8] + x[ 4], 13); x[ 0] ^= R(x[12] + x[ 8], 18);
wolfSSL 15:117db924cf7c 553 x[ 9] ^= R(x[ 5] + x[ 1], 7); x[13] ^= R(x[ 9] + x[ 5], 9);
wolfSSL 15:117db924cf7c 554 x[ 1] ^= R(x[13] + x[ 9], 13); x[ 5] ^= R(x[ 1] + x[13], 18);
wolfSSL 15:117db924cf7c 555 x[14] ^= R(x[10] + x[ 6], 7); x[ 2] ^= R(x[14] + x[10], 9);
wolfSSL 15:117db924cf7c 556 x[ 6] ^= R(x[ 2] + x[14], 13); x[10] ^= R(x[ 6] + x[ 2], 18);
wolfSSL 15:117db924cf7c 557 x[ 3] ^= R(x[15] + x[11], 7); x[ 7] ^= R(x[ 3] + x[15], 9);
wolfSSL 15:117db924cf7c 558 x[11] ^= R(x[ 7] + x[ 3], 13); x[15] ^= R(x[11] + x[ 7], 18);
wolfSSL 15:117db924cf7c 559 x[ 1] ^= R(x[ 0] + x[ 3], 7); x[ 2] ^= R(x[ 1] + x[ 0], 9);
wolfSSL 15:117db924cf7c 560 x[ 3] ^= R(x[ 2] + x[ 1], 13); x[ 0] ^= R(x[ 3] + x[ 2], 18);
wolfSSL 15:117db924cf7c 561 x[ 6] ^= R(x[ 5] + x[ 4], 7); x[ 7] ^= R(x[ 6] + x[ 5], 9);
wolfSSL 15:117db924cf7c 562 x[ 4] ^= R(x[ 7] + x[ 6], 13); x[ 5] ^= R(x[ 4] + x[ 7], 18);
wolfSSL 15:117db924cf7c 563 x[11] ^= R(x[10] + x[ 9], 7); x[ 8] ^= R(x[11] + x[10], 9);
wolfSSL 15:117db924cf7c 564 x[ 9] ^= R(x[ 8] + x[11], 13); x[10] ^= R(x[ 9] + x[ 8], 18);
wolfSSL 15:117db924cf7c 565 x[12] ^= R(x[15] + x[14], 7); x[13] ^= R(x[12] + x[15], 9);
wolfSSL 15:117db924cf7c 566 x[14] ^= R(x[13] + x[12], 13); x[15] ^= R(x[14] + x[13], 18);
wolfSSL 15:117db924cf7c 567 }
wolfSSL 15:117db924cf7c 568 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 15:117db924cf7c 569 for (i = 0; i < 16; ++i)
wolfSSL 15:117db924cf7c 570 out[i] = in[i] + x[i];
wolfSSL 15:117db924cf7c 571 #else
wolfSSL 15:117db924cf7c 572 for (i = 0; i < 16; i++)
wolfSSL 15:117db924cf7c 573 out[i] = ByteReverseWord32(ByteReverseWord32(in[i]) + x[i]);
wolfSSL 15:117db924cf7c 574 #endif
wolfSSL 15:117db924cf7c 575 }
wolfSSL 15:117db924cf7c 576
wolfSSL 15:117db924cf7c 577 /* Mix a block using Salsa20/8.
wolfSSL 15:117db924cf7c 578 * Based on RFC 7914: scrypt PBKDF.
wolfSSL 15:117db924cf7c 579 *
wolfSSL 15:117db924cf7c 580 * b Blocks to mix.
wolfSSL 15:117db924cf7c 581 * y Temporary storage.
wolfSSL 15:117db924cf7c 582 * r Size of the block.
wolfSSL 15:117db924cf7c 583 */
wolfSSL 15:117db924cf7c 584 static void scryptBlockMix(byte* b, byte* y, int r)
wolfSSL 15:117db924cf7c 585 {
wolfSSL 15:117db924cf7c 586 byte x[64];
wolfSSL 15:117db924cf7c 587 #ifdef WORD64_AVAILABLE
wolfSSL 15:117db924cf7c 588 word64* b64 = (word64*)b;
wolfSSL 15:117db924cf7c 589 word64* y64 = (word64*)y;
wolfSSL 15:117db924cf7c 590 word64* x64 = (word64*)x;
wolfSSL 15:117db924cf7c 591 #else
wolfSSL 15:117db924cf7c 592 word32* b32 = (word32*)b;
wolfSSL 15:117db924cf7c 593 word32* y32 = (word32*)y;
wolfSSL 15:117db924cf7c 594 word32* x32 = (word32*)x;
wolfSSL 15:117db924cf7c 595 #endif
wolfSSL 15:117db924cf7c 596 int i;
wolfSSL 15:117db924cf7c 597 int j;
wolfSSL 15:117db924cf7c 598
wolfSSL 15:117db924cf7c 599 /* Step 1. */
wolfSSL 15:117db924cf7c 600 XMEMCPY(x, b + (2 * r - 1) * 64, sizeof(x));
wolfSSL 15:117db924cf7c 601 /* Step 2. */
wolfSSL 15:117db924cf7c 602 for (i = 0; i < 2 * r; i++)
wolfSSL 15:117db924cf7c 603 {
wolfSSL 15:117db924cf7c 604 #ifdef WORD64_AVAILABLE
wolfSSL 15:117db924cf7c 605 for (j = 0; j < 8; j++)
wolfSSL 15:117db924cf7c 606 x64[j] ^= b64[i * 8 + j];
wolfSSL 15:117db924cf7c 607 #else
wolfSSL 15:117db924cf7c 608 for (j = 0; j < 16; j++)
wolfSSL 15:117db924cf7c 609 x32[j] ^= b32[i * 16 + j];
wolfSSL 15:117db924cf7c 610 #endif
wolfSSL 15:117db924cf7c 611 scryptSalsa((word32*)x, (word32*)x);
wolfSSL 15:117db924cf7c 612 XMEMCPY(y + i * 64, x, sizeof(x));
wolfSSL 15:117db924cf7c 613 }
wolfSSL 15:117db924cf7c 614 /* Step 3. */
wolfSSL 15:117db924cf7c 615 for (i = 0; i < r; i++) {
wolfSSL 15:117db924cf7c 616 #ifdef WORD64_AVAILABLE
wolfSSL 15:117db924cf7c 617 for (j = 0; j < 8; j++) {
wolfSSL 15:117db924cf7c 618 b64[i * 8 + j] = y64[2 * i * 8 + j];
wolfSSL 15:117db924cf7c 619 b64[(r + i) * 8 + j] = y64[(2 * i + 1) * 8 + j];
wolfSSL 15:117db924cf7c 620 }
wolfSSL 15:117db924cf7c 621 #else
wolfSSL 15:117db924cf7c 622 for (j = 0; j < 16; j++) {
wolfSSL 15:117db924cf7c 623 b32[i * 16 + j] = y32[2 * i * 16 + j];
wolfSSL 15:117db924cf7c 624 b32[(r + i) * 16 + j] = y32[(2 * i + 1) * 16 + j];
wolfSSL 15:117db924cf7c 625 }
wolfSSL 15:117db924cf7c 626 #endif
wolfSSL 15:117db924cf7c 627 }
wolfSSL 15:117db924cf7c 628 }
wolfSSL 15:117db924cf7c 629
wolfSSL 15:117db924cf7c 630 /* Random oracles mix.
wolfSSL 15:117db924cf7c 631 * Based on RFC 7914: scrypt PBKDF.
wolfSSL 15:117db924cf7c 632 *
wolfSSL 15:117db924cf7c 633 * x Data to mix.
wolfSSL 15:117db924cf7c 634 * v Temporary buffer.
wolfSSL 15:117db924cf7c 635 * y Temporary buffer for the block mix.
wolfSSL 15:117db924cf7c 636 * r Block size parameter.
wolfSSL 15:117db924cf7c 637 * n CPU/Memory cost parameter.
wolfSSL 15:117db924cf7c 638 */
wolfSSL 15:117db924cf7c 639 static void scryptROMix(byte* x, byte* v, byte* y, int r, word32 n)
wolfSSL 15:117db924cf7c 640 {
wolfSSL 15:117db924cf7c 641 word32 i;
wolfSSL 15:117db924cf7c 642 word32 j;
wolfSSL 15:117db924cf7c 643 word32 k;
wolfSSL 15:117db924cf7c 644 word32 bSz = 128 * r;
wolfSSL 15:117db924cf7c 645 #ifdef WORD64_AVAILABLE
wolfSSL 15:117db924cf7c 646 word64* x64 = (word64*)x;
wolfSSL 15:117db924cf7c 647 word64* v64 = (word64*)v;
wolfSSL 15:117db924cf7c 648 #else
wolfSSL 15:117db924cf7c 649 word32* x32 = (word32*)x;
wolfSSL 15:117db924cf7c 650 word32* v32 = (word32*)v;
wolfSSL 15:117db924cf7c 651 #endif
wolfSSL 15:117db924cf7c 652
wolfSSL 15:117db924cf7c 653 /* Step 1. X = B (B not needed therefore not implemented) */
wolfSSL 15:117db924cf7c 654 /* Step 2. */
wolfSSL 15:117db924cf7c 655 for (i = 0; i < n; i++)
wolfSSL 15:117db924cf7c 656 {
wolfSSL 15:117db924cf7c 657 XMEMCPY(v + i * bSz, x, bSz);
wolfSSL 15:117db924cf7c 658 scryptBlockMix(x, y, r);
wolfSSL 15:117db924cf7c 659 }
wolfSSL 15:117db924cf7c 660
wolfSSL 15:117db924cf7c 661 /* Step 3. */
wolfSSL 15:117db924cf7c 662 for (i = 0; i < n; i++)
wolfSSL 15:117db924cf7c 663 {
wolfSSL 15:117db924cf7c 664 #ifdef LITTLE_ENDIAN_ORDER
wolfSSL 15:117db924cf7c 665 #ifdef WORD64_AVAILABLE
wolfSSL 15:117db924cf7c 666 j = *(word64*)(x + (2*r - 1) * 64) & (n-1);
wolfSSL 15:117db924cf7c 667 #else
wolfSSL 15:117db924cf7c 668 j = *(word32*)(x + (2*r - 1) * 64) & (n-1);
wolfSSL 15:117db924cf7c 669 #endif
wolfSSL 15:117db924cf7c 670 #else
wolfSSL 15:117db924cf7c 671 byte* t = x + (2*r - 1) * 64;
wolfSSL 15:117db924cf7c 672 j = (t[0] | (t[1] << 8) | (t[2] << 16) | ((word32)t[3] << 24)) & (n-1);
wolfSSL 15:117db924cf7c 673 #endif
wolfSSL 15:117db924cf7c 674 #ifdef WORD64_AVAILABLE
wolfSSL 15:117db924cf7c 675 for (k = 0; k < bSz / 8; k++)
wolfSSL 15:117db924cf7c 676 x64[k] ^= v64[j * bSz / 8 + k];
wolfSSL 15:117db924cf7c 677 #else
wolfSSL 15:117db924cf7c 678 for (k = 0; k < bSz / 4; k++)
wolfSSL 15:117db924cf7c 679 x32[k] ^= v32[j * bSz / 4 + k];
wolfSSL 15:117db924cf7c 680 #endif
wolfSSL 15:117db924cf7c 681 scryptBlockMix(x, y, r);
wolfSSL 15:117db924cf7c 682 }
wolfSSL 15:117db924cf7c 683 /* Step 4. B' = X (B = X = B' so not needed, therefore not implemented) */
wolfSSL 15:117db924cf7c 684 }
wolfSSL 15:117db924cf7c 685
wolfSSL 15:117db924cf7c 686 /* Generates an key derived from a password and salt using a memory hard
wolfSSL 15:117db924cf7c 687 * algorithm.
wolfSSL 15:117db924cf7c 688 * Implements RFC 7914: scrypt PBKDF.
wolfSSL 15:117db924cf7c 689 *
wolfSSL 15:117db924cf7c 690 * output The derived key.
wolfSSL 15:117db924cf7c 691 * passwd The password to derive key from.
wolfSSL 15:117db924cf7c 692 * passLen The length of the password.
wolfSSL 15:117db924cf7c 693 * salt The key specific data.
wolfSSL 15:117db924cf7c 694 * saltLen The length of the salt data.
wolfSSL 15:117db924cf7c 695 * cost The CPU/memory cost parameter. Range: 1..(128*r/8-1)
wolfSSL 15:117db924cf7c 696 * (Iterations = 2^cost)
wolfSSL 15:117db924cf7c 697 * blockSize The number of 128 byte octets in a working block.
wolfSSL 15:117db924cf7c 698 * parallel The number of parallel mix operations to perform.
wolfSSL 15:117db924cf7c 699 * (Note: this implementation does not use threads.)
wolfSSL 15:117db924cf7c 700 * dkLen The length of the derived key in bytes.
wolfSSL 16:8e0d178b1d1e 701 * returns BAD_FUNC_ARG when: blockSize is too large for cost.
wolfSSL 15:117db924cf7c 702 */
wolfSSL 15:117db924cf7c 703 int wc_scrypt(byte* output, const byte* passwd, int passLen,
wolfSSL 15:117db924cf7c 704 const byte* salt, int saltLen, int cost, int blockSize,
wolfSSL 15:117db924cf7c 705 int parallel, int dkLen)
wolfSSL 15:117db924cf7c 706 {
wolfSSL 15:117db924cf7c 707 int ret = 0;
wolfSSL 15:117db924cf7c 708 int i;
wolfSSL 15:117db924cf7c 709 byte* v = NULL;
wolfSSL 15:117db924cf7c 710 byte* y = NULL;
wolfSSL 15:117db924cf7c 711 byte* blocks = NULL;
wolfSSL 15:117db924cf7c 712 word32 blocksSz;
wolfSSL 15:117db924cf7c 713 word32 bSz;
wolfSSL 15:117db924cf7c 714
wolfSSL 15:117db924cf7c 715 if (blockSize > 8)
wolfSSL 15:117db924cf7c 716 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 717
wolfSSL 16:8e0d178b1d1e 718 if (cost < 1 || cost >= 128 * blockSize / 8 || parallel < 1 || dkLen < 1)
wolfSSL 15:117db924cf7c 719 return BAD_FUNC_ARG;
wolfSSL 15:117db924cf7c 720
wolfSSL 15:117db924cf7c 721 bSz = 128 * blockSize;
wolfSSL 15:117db924cf7c 722 blocksSz = bSz * parallel;
wolfSSL 15:117db924cf7c 723 blocks = (byte*)XMALLOC(blocksSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 724 if (blocks == NULL)
wolfSSL 15:117db924cf7c 725 goto end;
wolfSSL 15:117db924cf7c 726 /* Temporary for scryptROMix. */
wolfSSL 15:117db924cf7c 727 v = (byte*)XMALLOC((1 << cost) * bSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 728 if (v == NULL)
wolfSSL 15:117db924cf7c 729 goto end;
wolfSSL 15:117db924cf7c 730 /* Temporary for scryptBlockMix. */
wolfSSL 15:117db924cf7c 731 y = (byte*)XMALLOC(blockSize * 128, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 732 if (y == NULL)
wolfSSL 15:117db924cf7c 733 goto end;
wolfSSL 15:117db924cf7c 734
wolfSSL 15:117db924cf7c 735 /* Step 1. */
wolfSSL 15:117db924cf7c 736 ret = wc_PBKDF2(blocks, passwd, passLen, salt, saltLen, 1, blocksSz,
wolfSSL 15:117db924cf7c 737 WC_SHA256);
wolfSSL 15:117db924cf7c 738 if (ret != 0)
wolfSSL 15:117db924cf7c 739 goto end;
wolfSSL 15:117db924cf7c 740
wolfSSL 15:117db924cf7c 741 /* Step 2. */
wolfSSL 15:117db924cf7c 742 for (i = 0; i < parallel; i++)
wolfSSL 15:117db924cf7c 743 scryptROMix(blocks + i * bSz, v, y, blockSize, 1 << cost);
wolfSSL 15:117db924cf7c 744
wolfSSL 15:117db924cf7c 745 /* Step 3. */
wolfSSL 15:117db924cf7c 746 ret = wc_PBKDF2(output, passwd, passLen, blocks, blocksSz, 1, dkLen,
wolfSSL 15:117db924cf7c 747 WC_SHA256);
wolfSSL 15:117db924cf7c 748 end:
wolfSSL 15:117db924cf7c 749 if (blocks != NULL)
wolfSSL 15:117db924cf7c 750 XFREE(blocks, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 751 if (v != NULL)
wolfSSL 15:117db924cf7c 752 XFREE(v, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 753 if (y != NULL)
wolfSSL 15:117db924cf7c 754 XFREE(y, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 15:117db924cf7c 755
wolfSSL 15:117db924cf7c 756 return ret;
wolfSSL 15:117db924cf7c 757 }
wolfSSL 15:117db924cf7c 758
wolfSSL 16:8e0d178b1d1e 759 /* Generates an key derived from a password and salt using a memory hard
wolfSSL 16:8e0d178b1d1e 760 * algorithm.
wolfSSL 16:8e0d178b1d1e 761 * Implements RFC 7914: scrypt PBKDF.
wolfSSL 16:8e0d178b1d1e 762 *
wolfSSL 16:8e0d178b1d1e 763 * output Derived key.
wolfSSL 16:8e0d178b1d1e 764 * passwd Password to derive key from.
wolfSSL 16:8e0d178b1d1e 765 * passLen Length of the password.
wolfSSL 16:8e0d178b1d1e 766 * salt Key specific data.
wolfSSL 16:8e0d178b1d1e 767 * saltLen Length of the salt data.
wolfSSL 16:8e0d178b1d1e 768 * iterations Number of iterations to perform. Range: 1 << (1..(128*r/8-1))
wolfSSL 16:8e0d178b1d1e 769 * blockSize Number of 128 byte octets in a working block.
wolfSSL 16:8e0d178b1d1e 770 * parallel Number of parallel mix operations to perform.
wolfSSL 16:8e0d178b1d1e 771 * (Note: this implementation does not use threads.)
wolfSSL 16:8e0d178b1d1e 772 * dkLen Length of the derived key in bytes.
wolfSSL 16:8e0d178b1d1e 773 * returns BAD_FUNC_ARG when: iterations is not a power of 2 or blockSize is too
wolfSSL 16:8e0d178b1d1e 774 * large for iterations.
wolfSSL 16:8e0d178b1d1e 775 */
wolfSSL 16:8e0d178b1d1e 776 int wc_scrypt_ex(byte* output, const byte* passwd, int passLen,
wolfSSL 16:8e0d178b1d1e 777 const byte* salt, int saltLen, word32 iterations,
wolfSSL 16:8e0d178b1d1e 778 int blockSize, int parallel, int dkLen)
wolfSSL 16:8e0d178b1d1e 779 {
wolfSSL 16:8e0d178b1d1e 780 int cost;
wolfSSL 16:8e0d178b1d1e 781
wolfSSL 16:8e0d178b1d1e 782 /* Iterations must be a power of 2. */
wolfSSL 16:8e0d178b1d1e 783 if ((iterations & (iterations - 1)) != 0)
wolfSSL 16:8e0d178b1d1e 784 return BAD_FUNC_ARG;
wolfSSL 16:8e0d178b1d1e 785
wolfSSL 16:8e0d178b1d1e 786 for (cost = -1; iterations != 0; cost++) {
wolfSSL 16:8e0d178b1d1e 787 iterations >>= 1;
wolfSSL 16:8e0d178b1d1e 788 }
wolfSSL 16:8e0d178b1d1e 789
wolfSSL 16:8e0d178b1d1e 790 return wc_scrypt(output, passwd, passLen, salt, saltLen, cost, blockSize,
wolfSSL 16:8e0d178b1d1e 791 parallel, dkLen);
wolfSSL 16:8e0d178b1d1e 792 }
wolfSSL 16:8e0d178b1d1e 793 #endif /* HAVE_SCRYPT */
wolfSSL 15:117db924cf7c 794
wolfSSL 15:117db924cf7c 795 #endif /* NO_PWDBASED */
wolfSSL 15:117db924cf7c 796