Fork of CyaSSL for my specific settings

Dependents:   CyaSSL_Example

Fork of CyaSSL by wolf SSL

Committer:
d0773d
Date:
Tue Mar 03 22:52:52 2015 +0000
Revision:
4:28ac50e1d49c
Parent:
0:1239e9b70ca2
CyaSSL example

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wolfSSL 0:1239e9b70ca2 1 /* pwdbased.c
wolfSSL 0:1239e9b70ca2 2 *
wolfSSL 0:1239e9b70ca2 3 * Copyright (C) 2006-2014 wolfSSL Inc.
wolfSSL 0:1239e9b70ca2 4 *
wolfSSL 0:1239e9b70ca2 5 * This file is part of CyaSSL.
wolfSSL 0:1239e9b70ca2 6 *
wolfSSL 0:1239e9b70ca2 7 * CyaSSL is free software; you can redistribute it and/or modify
wolfSSL 0:1239e9b70ca2 8 * it under the terms of the GNU General Public License as published by
wolfSSL 0:1239e9b70ca2 9 * the Free Software Foundation; either version 2 of the License, or
wolfSSL 0:1239e9b70ca2 10 * (at your option) any later version.
wolfSSL 0:1239e9b70ca2 11 *
wolfSSL 0:1239e9b70ca2 12 * CyaSSL is distributed in the hope that it will be useful,
wolfSSL 0:1239e9b70ca2 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
wolfSSL 0:1239e9b70ca2 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
wolfSSL 0:1239e9b70ca2 15 * GNU General Public License for more details.
wolfSSL 0:1239e9b70ca2 16 *
wolfSSL 0:1239e9b70ca2 17 * You should have received a copy of the GNU General Public License
wolfSSL 0:1239e9b70ca2 18 * along with this program; if not, write to the Free Software
wolfSSL 0:1239e9b70ca2 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
wolfSSL 0:1239e9b70ca2 20 */
wolfSSL 0:1239e9b70ca2 21
wolfSSL 0:1239e9b70ca2 22 #ifdef HAVE_CONFIG_H
wolfSSL 0:1239e9b70ca2 23 #include <config.h>
wolfSSL 0:1239e9b70ca2 24 #endif
wolfSSL 0:1239e9b70ca2 25
wolfSSL 0:1239e9b70ca2 26 #include <cyassl/ctaocrypt/settings.h>
wolfSSL 0:1239e9b70ca2 27
wolfSSL 0:1239e9b70ca2 28 #ifndef NO_PWDBASED
wolfSSL 0:1239e9b70ca2 29
wolfSSL 0:1239e9b70ca2 30 #ifdef CYASSL_PIC32MZ_HASH
wolfSSL 0:1239e9b70ca2 31
wolfSSL 0:1239e9b70ca2 32 #define InitMd5 InitMd5_sw
wolfSSL 0:1239e9b70ca2 33 #define Md5Update Md5Update_sw
wolfSSL 0:1239e9b70ca2 34 #define Md5Final Md5Final_sw
wolfSSL 0:1239e9b70ca2 35
wolfSSL 0:1239e9b70ca2 36 #define InitSha InitSha_sw
wolfSSL 0:1239e9b70ca2 37 #define ShaUpdate ShaUpdate_sw
wolfSSL 0:1239e9b70ca2 38 #define ShaFinal ShaFinal_sw
wolfSSL 0:1239e9b70ca2 39
wolfSSL 0:1239e9b70ca2 40 #define InitSha256 InitSha256_sw
wolfSSL 0:1239e9b70ca2 41 #define Sha256Update Sha256Update_sw
wolfSSL 0:1239e9b70ca2 42 #define Sha256Final Sha256Final_sw
wolfSSL 0:1239e9b70ca2 43
wolfSSL 0:1239e9b70ca2 44 #endif
wolfSSL 0:1239e9b70ca2 45
wolfSSL 0:1239e9b70ca2 46 #include <cyassl/ctaocrypt/pwdbased.h>
wolfSSL 0:1239e9b70ca2 47 #include <cyassl/ctaocrypt/hmac.h>
wolfSSL 0:1239e9b70ca2 48 #include <cyassl/ctaocrypt/integer.h>
wolfSSL 0:1239e9b70ca2 49 #include <cyassl/ctaocrypt/error-crypt.h>
wolfSSL 0:1239e9b70ca2 50 #if defined(CYASSL_SHA512) || defined(CYASSL_SHA384)
wolfSSL 0:1239e9b70ca2 51 #include <cyassl/ctaocrypt/sha512.h>
wolfSSL 0:1239e9b70ca2 52 #endif
wolfSSL 0:1239e9b70ca2 53
wolfSSL 0:1239e9b70ca2 54 #ifdef NO_INLINE
wolfSSL 0:1239e9b70ca2 55 #include <cyassl/ctaocrypt/misc.h>
wolfSSL 0:1239e9b70ca2 56 #else
wolfSSL 0:1239e9b70ca2 57 #include <ctaocrypt/src/misc.c>
wolfSSL 0:1239e9b70ca2 58 #endif
wolfSSL 0:1239e9b70ca2 59
wolfSSL 0:1239e9b70ca2 60
wolfSSL 0:1239e9b70ca2 61 #ifndef min
wolfSSL 0:1239e9b70ca2 62
wolfSSL 0:1239e9b70ca2 63 static INLINE word32 min(word32 a, word32 b)
wolfSSL 0:1239e9b70ca2 64 {
wolfSSL 0:1239e9b70ca2 65 return a > b ? b : a;
wolfSSL 0:1239e9b70ca2 66 }
wolfSSL 0:1239e9b70ca2 67
wolfSSL 0:1239e9b70ca2 68 #endif /* min */
wolfSSL 0:1239e9b70ca2 69
wolfSSL 0:1239e9b70ca2 70
wolfSSL 0:1239e9b70ca2 71 int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
wolfSSL 0:1239e9b70ca2 72 int sLen, int iterations, int kLen, int hashType)
wolfSSL 0:1239e9b70ca2 73 {
wolfSSL 0:1239e9b70ca2 74 Md5 md5;
wolfSSL 0:1239e9b70ca2 75 Sha sha;
wolfSSL 0:1239e9b70ca2 76 int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 77 int i, ret = 0;
wolfSSL 0:1239e9b70ca2 78 byte buffer[SHA_DIGEST_SIZE]; /* max size */
wolfSSL 0:1239e9b70ca2 79
wolfSSL 0:1239e9b70ca2 80 if (hashType != MD5 && hashType != SHA)
wolfSSL 0:1239e9b70ca2 81 return BAD_FUNC_ARG;
wolfSSL 0:1239e9b70ca2 82
wolfSSL 0:1239e9b70ca2 83 if (kLen > hLen)
wolfSSL 0:1239e9b70ca2 84 return BAD_FUNC_ARG;
wolfSSL 0:1239e9b70ca2 85
wolfSSL 0:1239e9b70ca2 86 if (iterations < 1)
wolfSSL 0:1239e9b70ca2 87 return BAD_FUNC_ARG;
wolfSSL 0:1239e9b70ca2 88
wolfSSL 0:1239e9b70ca2 89 if (hashType == MD5) {
wolfSSL 0:1239e9b70ca2 90 InitMd5(&md5);
wolfSSL 0:1239e9b70ca2 91 Md5Update(&md5, passwd, pLen);
wolfSSL 0:1239e9b70ca2 92 Md5Update(&md5, salt, sLen);
wolfSSL 0:1239e9b70ca2 93 Md5Final(&md5, buffer);
wolfSSL 0:1239e9b70ca2 94 }
wolfSSL 0:1239e9b70ca2 95 else {
wolfSSL 0:1239e9b70ca2 96 ret = InitSha(&sha);
wolfSSL 0:1239e9b70ca2 97 if (ret != 0)
wolfSSL 0:1239e9b70ca2 98 return ret;
wolfSSL 0:1239e9b70ca2 99 ShaUpdate(&sha, passwd, pLen);
wolfSSL 0:1239e9b70ca2 100 ShaUpdate(&sha, salt, sLen);
wolfSSL 0:1239e9b70ca2 101 ShaFinal(&sha, buffer);
wolfSSL 0:1239e9b70ca2 102 }
wolfSSL 0:1239e9b70ca2 103
wolfSSL 0:1239e9b70ca2 104 for (i = 1; i < iterations; i++) {
wolfSSL 0:1239e9b70ca2 105 if (hashType == MD5) {
wolfSSL 0:1239e9b70ca2 106 Md5Update(&md5, buffer, hLen);
wolfSSL 0:1239e9b70ca2 107 Md5Final(&md5, buffer);
wolfSSL 0:1239e9b70ca2 108 }
wolfSSL 0:1239e9b70ca2 109 else {
wolfSSL 0:1239e9b70ca2 110 ShaUpdate(&sha, buffer, hLen);
wolfSSL 0:1239e9b70ca2 111 ShaFinal(&sha, buffer);
wolfSSL 0:1239e9b70ca2 112 }
wolfSSL 0:1239e9b70ca2 113 }
wolfSSL 0:1239e9b70ca2 114 XMEMCPY(output, buffer, kLen);
wolfSSL 0:1239e9b70ca2 115
wolfSSL 0:1239e9b70ca2 116 return 0;
wolfSSL 0:1239e9b70ca2 117 }
wolfSSL 0:1239e9b70ca2 118
wolfSSL 0:1239e9b70ca2 119
wolfSSL 0:1239e9b70ca2 120 int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
wolfSSL 0:1239e9b70ca2 121 int sLen, int iterations, int kLen, int hashType)
wolfSSL 0:1239e9b70ca2 122 {
wolfSSL 0:1239e9b70ca2 123 word32 i = 1;
wolfSSL 0:1239e9b70ca2 124 int hLen;
wolfSSL 0:1239e9b70ca2 125 int j, ret;
wolfSSL 0:1239e9b70ca2 126 Hmac hmac;
wolfSSL 0:1239e9b70ca2 127 #ifdef CYASSL_SMALL_STACK
wolfSSL 0:1239e9b70ca2 128 byte* buffer;
wolfSSL 0:1239e9b70ca2 129 #else
wolfSSL 0:1239e9b70ca2 130 byte buffer[MAX_DIGEST_SIZE];
wolfSSL 0:1239e9b70ca2 131 #endif
wolfSSL 0:1239e9b70ca2 132
wolfSSL 0:1239e9b70ca2 133 if (hashType == MD5) {
wolfSSL 0:1239e9b70ca2 134 hLen = MD5_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 135 }
wolfSSL 0:1239e9b70ca2 136 else if (hashType == SHA) {
wolfSSL 0:1239e9b70ca2 137 hLen = SHA_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 138 }
wolfSSL 0:1239e9b70ca2 139 #ifndef NO_SHA256
wolfSSL 0:1239e9b70ca2 140 else if (hashType == SHA256) {
wolfSSL 0:1239e9b70ca2 141 hLen = SHA256_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 142 }
wolfSSL 0:1239e9b70ca2 143 #endif
wolfSSL 0:1239e9b70ca2 144 #ifdef CYASSL_SHA512
wolfSSL 0:1239e9b70ca2 145 else if (hashType == SHA512) {
wolfSSL 0:1239e9b70ca2 146 hLen = SHA512_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 147 }
wolfSSL 0:1239e9b70ca2 148 #endif
wolfSSL 0:1239e9b70ca2 149 else
wolfSSL 0:1239e9b70ca2 150 return BAD_FUNC_ARG;
wolfSSL 0:1239e9b70ca2 151
wolfSSL 0:1239e9b70ca2 152 #ifdef CYASSL_SMALL_STACK
wolfSSL 0:1239e9b70ca2 153 buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 154 if (buffer == NULL)
wolfSSL 0:1239e9b70ca2 155 return MEMORY_E;
wolfSSL 0:1239e9b70ca2 156 #endif
wolfSSL 0:1239e9b70ca2 157
wolfSSL 0:1239e9b70ca2 158 ret = HmacSetKey(&hmac, hashType, passwd, pLen);
wolfSSL 0:1239e9b70ca2 159
wolfSSL 0:1239e9b70ca2 160 if (ret == 0) {
wolfSSL 0:1239e9b70ca2 161 while (kLen) {
wolfSSL 0:1239e9b70ca2 162 int currentLen;
wolfSSL 0:1239e9b70ca2 163
wolfSSL 0:1239e9b70ca2 164 ret = HmacUpdate(&hmac, salt, sLen);
wolfSSL 0:1239e9b70ca2 165 if (ret != 0)
wolfSSL 0:1239e9b70ca2 166 break;
wolfSSL 0:1239e9b70ca2 167
wolfSSL 0:1239e9b70ca2 168 /* encode i */
wolfSSL 0:1239e9b70ca2 169 for (j = 0; j < 4; j++) {
wolfSSL 0:1239e9b70ca2 170 byte b = (byte)(i >> ((3-j) * 8));
wolfSSL 0:1239e9b70ca2 171
wolfSSL 0:1239e9b70ca2 172 ret = HmacUpdate(&hmac, &b, 1);
wolfSSL 0:1239e9b70ca2 173 if (ret != 0)
wolfSSL 0:1239e9b70ca2 174 break;
wolfSSL 0:1239e9b70ca2 175 }
wolfSSL 0:1239e9b70ca2 176
wolfSSL 0:1239e9b70ca2 177 /* check ret from inside for loop */
wolfSSL 0:1239e9b70ca2 178 if (ret != 0)
wolfSSL 0:1239e9b70ca2 179 break;
wolfSSL 0:1239e9b70ca2 180
wolfSSL 0:1239e9b70ca2 181 ret = HmacFinal(&hmac, buffer);
wolfSSL 0:1239e9b70ca2 182 if (ret != 0)
wolfSSL 0:1239e9b70ca2 183 break;
wolfSSL 0:1239e9b70ca2 184
wolfSSL 0:1239e9b70ca2 185 currentLen = min(kLen, hLen);
wolfSSL 0:1239e9b70ca2 186 XMEMCPY(output, buffer, currentLen);
wolfSSL 0:1239e9b70ca2 187
wolfSSL 0:1239e9b70ca2 188 for (j = 1; j < iterations; j++) {
wolfSSL 0:1239e9b70ca2 189 ret = HmacUpdate(&hmac, buffer, hLen);
wolfSSL 0:1239e9b70ca2 190 if (ret != 0)
wolfSSL 0:1239e9b70ca2 191 break;
wolfSSL 0:1239e9b70ca2 192 ret = HmacFinal(&hmac, buffer);
wolfSSL 0:1239e9b70ca2 193 if (ret != 0)
wolfSSL 0:1239e9b70ca2 194 break;
wolfSSL 0:1239e9b70ca2 195 xorbuf(output, buffer, currentLen);
wolfSSL 0:1239e9b70ca2 196 }
wolfSSL 0:1239e9b70ca2 197
wolfSSL 0:1239e9b70ca2 198 /* check ret from inside for loop */
wolfSSL 0:1239e9b70ca2 199 if (ret != 0)
wolfSSL 0:1239e9b70ca2 200 break;
wolfSSL 0:1239e9b70ca2 201
wolfSSL 0:1239e9b70ca2 202 output += currentLen;
wolfSSL 0:1239e9b70ca2 203 kLen -= currentLen;
wolfSSL 0:1239e9b70ca2 204 i++;
wolfSSL 0:1239e9b70ca2 205 }
wolfSSL 0:1239e9b70ca2 206 }
wolfSSL 0:1239e9b70ca2 207
wolfSSL 0:1239e9b70ca2 208 #ifdef CYASSL_SMALL_STACK
wolfSSL 0:1239e9b70ca2 209 XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 210 #endif
wolfSSL 0:1239e9b70ca2 211
wolfSSL 0:1239e9b70ca2 212 return ret;
wolfSSL 0:1239e9b70ca2 213 }
wolfSSL 0:1239e9b70ca2 214
wolfSSL 0:1239e9b70ca2 215 #ifdef CYASSL_SHA512
wolfSSL 0:1239e9b70ca2 216 #define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE
wolfSSL 0:1239e9b70ca2 217 #elif !defined(NO_SHA256)
wolfSSL 0:1239e9b70ca2 218 #define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE
wolfSSL 0:1239e9b70ca2 219 #else
wolfSSL 0:1239e9b70ca2 220 #define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE
wolfSSL 0:1239e9b70ca2 221 #endif
wolfSSL 0:1239e9b70ca2 222
wolfSSL 0:1239e9b70ca2 223 int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
wolfSSL 0:1239e9b70ca2 224 int saltLen, int iterations, int kLen, int hashType, int id)
wolfSSL 0:1239e9b70ca2 225 {
wolfSSL 0:1239e9b70ca2 226 /* all in bytes instead of bits */
wolfSSL 0:1239e9b70ca2 227 word32 u, v, dLen, pLen, iLen, sLen, totalLen;
wolfSSL 0:1239e9b70ca2 228 int dynamic = 0;
wolfSSL 0:1239e9b70ca2 229 int ret = 0;
wolfSSL 0:1239e9b70ca2 230 int i;
wolfSSL 0:1239e9b70ca2 231 byte *D, *S, *P, *I;
wolfSSL 0:1239e9b70ca2 232 #ifdef CYASSL_SMALL_STACK
wolfSSL 0:1239e9b70ca2 233 byte staticBuffer[1]; /* force dynamic usage */
wolfSSL 0:1239e9b70ca2 234 #else
wolfSSL 0:1239e9b70ca2 235 byte staticBuffer[1024];
wolfSSL 0:1239e9b70ca2 236 #endif
wolfSSL 0:1239e9b70ca2 237 byte* buffer = staticBuffer;
wolfSSL 0:1239e9b70ca2 238
wolfSSL 0:1239e9b70ca2 239 #ifdef CYASSL_SMALL_STACK
wolfSSL 0:1239e9b70ca2 240 byte* Ai;
wolfSSL 0:1239e9b70ca2 241 byte* B;
wolfSSL 0:1239e9b70ca2 242 #else
wolfSSL 0:1239e9b70ca2 243 byte Ai[PBKDF_DIGEST_SIZE];
wolfSSL 0:1239e9b70ca2 244 byte B[PBKDF_DIGEST_SIZE];
wolfSSL 0:1239e9b70ca2 245 #endif
wolfSSL 0:1239e9b70ca2 246
wolfSSL 0:1239e9b70ca2 247 if (!iterations)
wolfSSL 0:1239e9b70ca2 248 iterations = 1;
wolfSSL 0:1239e9b70ca2 249
wolfSSL 0:1239e9b70ca2 250 if (hashType == MD5) {
wolfSSL 0:1239e9b70ca2 251 v = MD5_BLOCK_SIZE;
wolfSSL 0:1239e9b70ca2 252 u = MD5_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 253 }
wolfSSL 0:1239e9b70ca2 254 else if (hashType == SHA) {
wolfSSL 0:1239e9b70ca2 255 v = SHA_BLOCK_SIZE;
wolfSSL 0:1239e9b70ca2 256 u = SHA_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 257 }
wolfSSL 0:1239e9b70ca2 258 #ifndef NO_SHA256
wolfSSL 0:1239e9b70ca2 259 else if (hashType == SHA256) {
wolfSSL 0:1239e9b70ca2 260 v = SHA256_BLOCK_SIZE;
wolfSSL 0:1239e9b70ca2 261 u = SHA256_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 262 }
wolfSSL 0:1239e9b70ca2 263 #endif
wolfSSL 0:1239e9b70ca2 264 #ifdef CYASSL_SHA512
wolfSSL 0:1239e9b70ca2 265 else if (hashType == SHA512) {
wolfSSL 0:1239e9b70ca2 266 v = SHA512_BLOCK_SIZE;
wolfSSL 0:1239e9b70ca2 267 u = SHA512_DIGEST_SIZE;
wolfSSL 0:1239e9b70ca2 268 }
wolfSSL 0:1239e9b70ca2 269 #endif
wolfSSL 0:1239e9b70ca2 270 else
wolfSSL 0:1239e9b70ca2 271 return BAD_FUNC_ARG;
wolfSSL 0:1239e9b70ca2 272
wolfSSL 0:1239e9b70ca2 273 #ifdef CYASSL_SMALL_STACK
wolfSSL 0:1239e9b70ca2 274 Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 275 if (Ai == NULL)
wolfSSL 0:1239e9b70ca2 276 return MEMORY_E;
wolfSSL 0:1239e9b70ca2 277
wolfSSL 0:1239e9b70ca2 278 B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 279 if (B == NULL) {
wolfSSL 0:1239e9b70ca2 280 XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 281 return MEMORY_E;
wolfSSL 0:1239e9b70ca2 282 }
wolfSSL 0:1239e9b70ca2 283 #endif
wolfSSL 0:1239e9b70ca2 284
wolfSSL 0:1239e9b70ca2 285 dLen = v;
wolfSSL 0:1239e9b70ca2 286 sLen = v * ((saltLen + v - 1) / v);
wolfSSL 0:1239e9b70ca2 287 if (passLen)
wolfSSL 0:1239e9b70ca2 288 pLen = v * ((passLen + v - 1) / v);
wolfSSL 0:1239e9b70ca2 289 else
wolfSSL 0:1239e9b70ca2 290 pLen = 0;
wolfSSL 0:1239e9b70ca2 291 iLen = sLen + pLen;
wolfSSL 0:1239e9b70ca2 292
wolfSSL 0:1239e9b70ca2 293 totalLen = dLen + sLen + pLen;
wolfSSL 0:1239e9b70ca2 294
wolfSSL 0:1239e9b70ca2 295 if (totalLen > sizeof(staticBuffer)) {
wolfSSL 0:1239e9b70ca2 296 buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY);
wolfSSL 0:1239e9b70ca2 297 if (buffer == NULL) {
wolfSSL 0:1239e9b70ca2 298 #ifdef CYASSL_SMALL_STACK
wolfSSL 0:1239e9b70ca2 299 XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 300 XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 301 #endif
wolfSSL 0:1239e9b70ca2 302 return MEMORY_E;
wolfSSL 0:1239e9b70ca2 303 }
wolfSSL 0:1239e9b70ca2 304 dynamic = 1;
wolfSSL 0:1239e9b70ca2 305 }
wolfSSL 0:1239e9b70ca2 306
wolfSSL 0:1239e9b70ca2 307 D = buffer;
wolfSSL 0:1239e9b70ca2 308 S = D + dLen;
wolfSSL 0:1239e9b70ca2 309 P = S + sLen;
wolfSSL 0:1239e9b70ca2 310 I = S;
wolfSSL 0:1239e9b70ca2 311
wolfSSL 0:1239e9b70ca2 312 XMEMSET(D, id, dLen);
wolfSSL 0:1239e9b70ca2 313
wolfSSL 0:1239e9b70ca2 314 for (i = 0; i < (int)sLen; i++)
wolfSSL 0:1239e9b70ca2 315 S[i] = salt[i % saltLen];
wolfSSL 0:1239e9b70ca2 316 for (i = 0; i < (int)pLen; i++)
wolfSSL 0:1239e9b70ca2 317 P[i] = passwd[i % passLen];
wolfSSL 0:1239e9b70ca2 318
wolfSSL 0:1239e9b70ca2 319 while (kLen > 0) {
wolfSSL 0:1239e9b70ca2 320 word32 currentLen;
wolfSSL 0:1239e9b70ca2 321 mp_int B1;
wolfSSL 0:1239e9b70ca2 322
wolfSSL 0:1239e9b70ca2 323 if (hashType == MD5) {
wolfSSL 0:1239e9b70ca2 324 Md5 md5;
wolfSSL 0:1239e9b70ca2 325
wolfSSL 0:1239e9b70ca2 326 InitMd5(&md5);
wolfSSL 0:1239e9b70ca2 327 Md5Update(&md5, buffer, totalLen);
wolfSSL 0:1239e9b70ca2 328 Md5Final(&md5, Ai);
wolfSSL 0:1239e9b70ca2 329
wolfSSL 0:1239e9b70ca2 330 for (i = 1; i < iterations; i++) {
wolfSSL 0:1239e9b70ca2 331 Md5Update(&md5, Ai, u);
wolfSSL 0:1239e9b70ca2 332 Md5Final(&md5, Ai);
wolfSSL 0:1239e9b70ca2 333 }
wolfSSL 0:1239e9b70ca2 334 }
wolfSSL 0:1239e9b70ca2 335 else if (hashType == SHA) {
wolfSSL 0:1239e9b70ca2 336 Sha sha;
wolfSSL 0:1239e9b70ca2 337
wolfSSL 0:1239e9b70ca2 338 ret = InitSha(&sha);
wolfSSL 0:1239e9b70ca2 339 if (ret != 0)
wolfSSL 0:1239e9b70ca2 340 break;
wolfSSL 0:1239e9b70ca2 341 ShaUpdate(&sha, buffer, totalLen);
wolfSSL 0:1239e9b70ca2 342 ShaFinal(&sha, Ai);
wolfSSL 0:1239e9b70ca2 343
wolfSSL 0:1239e9b70ca2 344 for (i = 1; i < iterations; i++) {
wolfSSL 0:1239e9b70ca2 345 ShaUpdate(&sha, Ai, u);
wolfSSL 0:1239e9b70ca2 346 ShaFinal(&sha, Ai);
wolfSSL 0:1239e9b70ca2 347 }
wolfSSL 0:1239e9b70ca2 348 }
wolfSSL 0:1239e9b70ca2 349 #ifndef NO_SHA256
wolfSSL 0:1239e9b70ca2 350 else if (hashType == SHA256) {
wolfSSL 0:1239e9b70ca2 351 Sha256 sha256;
wolfSSL 0:1239e9b70ca2 352
wolfSSL 0:1239e9b70ca2 353 ret = InitSha256(&sha256);
wolfSSL 0:1239e9b70ca2 354 if (ret != 0)
wolfSSL 0:1239e9b70ca2 355 break;
wolfSSL 0:1239e9b70ca2 356
wolfSSL 0:1239e9b70ca2 357 ret = Sha256Update(&sha256, buffer, totalLen);
wolfSSL 0:1239e9b70ca2 358 if (ret != 0)
wolfSSL 0:1239e9b70ca2 359 break;
wolfSSL 0:1239e9b70ca2 360
wolfSSL 0:1239e9b70ca2 361 ret = Sha256Final(&sha256, Ai);
wolfSSL 0:1239e9b70ca2 362 if (ret != 0)
wolfSSL 0:1239e9b70ca2 363 break;
wolfSSL 0:1239e9b70ca2 364
wolfSSL 0:1239e9b70ca2 365 for (i = 1; i < iterations; i++) {
wolfSSL 0:1239e9b70ca2 366 ret = Sha256Update(&sha256, Ai, u);
wolfSSL 0:1239e9b70ca2 367 if (ret != 0)
wolfSSL 0:1239e9b70ca2 368 break;
wolfSSL 0:1239e9b70ca2 369
wolfSSL 0:1239e9b70ca2 370 ret = Sha256Final(&sha256, Ai);
wolfSSL 0:1239e9b70ca2 371 if (ret != 0)
wolfSSL 0:1239e9b70ca2 372 break;
wolfSSL 0:1239e9b70ca2 373 }
wolfSSL 0:1239e9b70ca2 374 }
wolfSSL 0:1239e9b70ca2 375 #endif
wolfSSL 0:1239e9b70ca2 376 #ifdef CYASSL_SHA512
wolfSSL 0:1239e9b70ca2 377 else if (hashType == SHA512) {
wolfSSL 0:1239e9b70ca2 378 Sha512 sha512;
wolfSSL 0:1239e9b70ca2 379
wolfSSL 0:1239e9b70ca2 380 ret = InitSha512(&sha512);
wolfSSL 0:1239e9b70ca2 381 if (ret != 0)
wolfSSL 0:1239e9b70ca2 382 break;
wolfSSL 0:1239e9b70ca2 383
wolfSSL 0:1239e9b70ca2 384 ret = Sha512Update(&sha512, buffer, totalLen);
wolfSSL 0:1239e9b70ca2 385 if (ret != 0)
wolfSSL 0:1239e9b70ca2 386 break;
wolfSSL 0:1239e9b70ca2 387
wolfSSL 0:1239e9b70ca2 388 ret = Sha512Final(&sha512, Ai);
wolfSSL 0:1239e9b70ca2 389 if (ret != 0)
wolfSSL 0:1239e9b70ca2 390 break;
wolfSSL 0:1239e9b70ca2 391
wolfSSL 0:1239e9b70ca2 392 for (i = 1; i < iterations; i++) {
wolfSSL 0:1239e9b70ca2 393 ret = Sha512Update(&sha512, Ai, u);
wolfSSL 0:1239e9b70ca2 394 if (ret != 0)
wolfSSL 0:1239e9b70ca2 395 break;
wolfSSL 0:1239e9b70ca2 396
wolfSSL 0:1239e9b70ca2 397 ret = Sha512Final(&sha512, Ai);
wolfSSL 0:1239e9b70ca2 398 if (ret != 0)
wolfSSL 0:1239e9b70ca2 399 break;
wolfSSL 0:1239e9b70ca2 400 }
wolfSSL 0:1239e9b70ca2 401 }
wolfSSL 0:1239e9b70ca2 402 #endif
wolfSSL 0:1239e9b70ca2 403
wolfSSL 0:1239e9b70ca2 404 for (i = 0; i < (int)v; i++)
wolfSSL 0:1239e9b70ca2 405 B[i] = Ai[i % u];
wolfSSL 0:1239e9b70ca2 406
wolfSSL 0:1239e9b70ca2 407 if (mp_init(&B1) != MP_OKAY)
wolfSSL 0:1239e9b70ca2 408 ret = MP_INIT_E;
wolfSSL 0:1239e9b70ca2 409 else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)
wolfSSL 0:1239e9b70ca2 410 ret = MP_READ_E;
wolfSSL 0:1239e9b70ca2 411 else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY)
wolfSSL 0:1239e9b70ca2 412 ret = MP_ADD_E;
wolfSSL 0:1239e9b70ca2 413
wolfSSL 0:1239e9b70ca2 414 if (ret != 0) {
wolfSSL 0:1239e9b70ca2 415 mp_clear(&B1);
wolfSSL 0:1239e9b70ca2 416 break;
wolfSSL 0:1239e9b70ca2 417 }
wolfSSL 0:1239e9b70ca2 418
wolfSSL 0:1239e9b70ca2 419 for (i = 0; i < (int)iLen; i += v) {
wolfSSL 0:1239e9b70ca2 420 int outSz;
wolfSSL 0:1239e9b70ca2 421 mp_int i1;
wolfSSL 0:1239e9b70ca2 422 mp_int res;
wolfSSL 0:1239e9b70ca2 423
wolfSSL 0:1239e9b70ca2 424 if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) {
wolfSSL 0:1239e9b70ca2 425 ret = MP_INIT_E;
wolfSSL 0:1239e9b70ca2 426 break;
wolfSSL 0:1239e9b70ca2 427 }
wolfSSL 0:1239e9b70ca2 428 if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)
wolfSSL 0:1239e9b70ca2 429 ret = MP_READ_E;
wolfSSL 0:1239e9b70ca2 430 else if (mp_add(&i1, &B1, &res) != MP_OKAY)
wolfSSL 0:1239e9b70ca2 431 ret = MP_ADD_E;
wolfSSL 0:1239e9b70ca2 432 else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)
wolfSSL 0:1239e9b70ca2 433 ret = MP_TO_E;
wolfSSL 0:1239e9b70ca2 434 else {
wolfSSL 0:1239e9b70ca2 435 if (outSz > (int)v) {
wolfSSL 0:1239e9b70ca2 436 /* take off MSB */
wolfSSL 0:1239e9b70ca2 437 byte tmp[129];
wolfSSL 0:1239e9b70ca2 438 ret = mp_to_unsigned_bin(&res, tmp);
wolfSSL 0:1239e9b70ca2 439 XMEMCPY(I + i, tmp + 1, v);
wolfSSL 0:1239e9b70ca2 440 }
wolfSSL 0:1239e9b70ca2 441 else if (outSz < (int)v) {
wolfSSL 0:1239e9b70ca2 442 XMEMSET(I + i, 0, v - outSz);
wolfSSL 0:1239e9b70ca2 443 ret = mp_to_unsigned_bin(&res, I + i + v - outSz);
wolfSSL 0:1239e9b70ca2 444 }
wolfSSL 0:1239e9b70ca2 445 else
wolfSSL 0:1239e9b70ca2 446 ret = mp_to_unsigned_bin(&res, I + i);
wolfSSL 0:1239e9b70ca2 447 }
wolfSSL 0:1239e9b70ca2 448
wolfSSL 0:1239e9b70ca2 449 mp_clear(&i1);
wolfSSL 0:1239e9b70ca2 450 mp_clear(&res);
wolfSSL 0:1239e9b70ca2 451 if (ret < 0) break;
wolfSSL 0:1239e9b70ca2 452 }
wolfSSL 0:1239e9b70ca2 453
wolfSSL 0:1239e9b70ca2 454 currentLen = min(kLen, (int)u);
wolfSSL 0:1239e9b70ca2 455 XMEMCPY(output, Ai, currentLen);
wolfSSL 0:1239e9b70ca2 456 output += currentLen;
wolfSSL 0:1239e9b70ca2 457 kLen -= currentLen;
wolfSSL 0:1239e9b70ca2 458 mp_clear(&B1);
wolfSSL 0:1239e9b70ca2 459 }
wolfSSL 0:1239e9b70ca2 460
wolfSSL 0:1239e9b70ca2 461 if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY);
wolfSSL 0:1239e9b70ca2 462
wolfSSL 0:1239e9b70ca2 463 #ifdef CYASSL_SMALL_STACK
wolfSSL 0:1239e9b70ca2 464 XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 465 XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wolfSSL 0:1239e9b70ca2 466 #endif
wolfSSL 0:1239e9b70ca2 467
wolfSSL 0:1239e9b70ca2 468 return ret;
wolfSSL 0:1239e9b70ca2 469 }
wolfSSL 0:1239e9b70ca2 470
wolfSSL 0:1239e9b70ca2 471 #undef PBKDF_DIGEST_SIZE
wolfSSL 0:1239e9b70ca2 472
wolfSSL 0:1239e9b70ca2 473 #endif /* NO_PWDBASED */
wolfSSL 0:1239e9b70ca2 474
wolfSSL 0:1239e9b70ca2 475