Xuyi Wang / wolfSSL

Dependents:   OS

Committer:
wolfSSL
Date:
Fri Jun 26 00:39:20 2015 +0000
Revision:
0:d92f9d21154c
wolfSSL 3.6.0

Who changed what in which revision?

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