wolfSSL 3.11.1 for TLS1.3 beta

Fork of wolfSSL by wolf SSL

Committer:
wolfSSL
Date:
Tue May 30 06:16:19 2017 +0000
Revision:
13:80fb167dafdf
Parent:
11:cee25a834751
wolfSSL 3.11.1: TLS1.3 Beta

Who changed what in which revision?

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