Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Tue May 02 08:44:47 2017 +0000
Revision:
7:481bce714567
wolfSSL3.10.2

Who changed what in which revision?

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