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

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

Committer:
wolfSSL
Date:
Tue Aug 22 10:48:22 2017 +0000
Revision:
13:f67a6c6013ca
wolfSSL3.12.0 with TLS1.3

Who changed what in which revision?

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