Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of wolfSSL by
Diff: wolfcrypt/src/pwdbased.c
- Revision:
- 3:6f956bdb3073
- Parent:
- 2:28278596c2a2
- Child:
- 4:1b0d80432c79
--- a/wolfcrypt/src/pwdbased.c Tue Jul 21 11:37:09 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,563 +0,0 @@
-/* pwdbased.c
- *
- * Copyright (C) 2006-2015 wolfSSL Inc.
- *
- * This file is part of wolfSSL. (formerly known as CyaSSL)
- *
- * wolfSSL is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * wolfSSL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifdef HAVE_CONFIG_H
- #include <config.h>
-#endif
-
-#include <wolfssl/wolfcrypt/settings.h>
-
-#ifndef NO_PWDBASED
-
-#ifdef WOLFSSL_PIC32MZ_HASH
- #ifndef NO_MD5
- #define wc_InitMd5 wc_InitMd5_sw
- #define wc_Md5Update wc_Md5Update_sw
- #define wc_Md5Final wc_Md5Final_sw
- #endif /* NO_MD5 */
-
- #define wc_InitSha wc_InitSha_sw
- #define wc_ShaUpdate wc_ShaUpdate_sw
- #define wc_ShaFinal wc_ShaFinal_sw
-
- #define wc_InitSha256 wc_InitSha256_sw
- #define wc_Sha256Update wc_Sha256Update_sw
- #define wc_Sha256Final wc_Sha256Final_sw
-#endif
-
-#include <wolfssl/wolfcrypt/pwdbased.h>
-#include <wolfssl/wolfcrypt/hmac.h>
-#include <wolfssl/wolfcrypt/integer.h>
-#include <wolfssl/wolfcrypt/error-crypt.h>
-#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
- #include <wolfssl/wolfcrypt/sha512.h>
-#endif
-
-#ifdef NO_INLINE
- #include <wolfssl/wolfcrypt/misc.h>
-#else
- #include <wolfcrypt/src/misc.c>
-#endif
-
-#ifndef WOLFSSL_HAVE_MIN
-#define WOLFSSL_HAVE_MIN
-
- static INLINE word32 min(word32 a, word32 b)
- {
- return a > b ? b : a;
- }
-
-#endif /* WOLFSSL_HAVE_MIN */
-
-
-#ifndef NO_SHA
-/* PBKDF1 needs at least SHA available */
-int wc_PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
- int sLen, int iterations, int kLen, int hashType)
-{
- Sha sha;
-#ifndef NO_MD5
- Md5 md5;
-#endif
- int hLen = (int)SHA_DIGEST_SIZE;
- int i, ret = 0;
- byte buffer[SHA_DIGEST_SIZE]; /* max size */
-
- if (hashType != MD5 && hashType != SHA)
- return BAD_FUNC_ARG;
-
-#ifndef NO_MD5
- if (hashType == MD5)
- hLen = (int)MD5_DIGEST_SIZE;
-#endif
-
- if (kLen > hLen)
- return BAD_FUNC_ARG;
-
- if (iterations < 1)
- return BAD_FUNC_ARG;
-
- switch (hashType) {
-#ifndef NO_MD5
- case MD5:
- wc_InitMd5(&md5);
- wc_Md5Update(&md5, passwd, pLen);
- wc_Md5Update(&md5, salt, sLen);
- wc_Md5Final(&md5, buffer);
- break;
-#endif /* NO_MD5 */
- case SHA:
- default:
- ret = wc_InitSha(&sha);
- if (ret != 0)
- return ret;
- wc_ShaUpdate(&sha, passwd, pLen);
- wc_ShaUpdate(&sha, salt, sLen);
- wc_ShaFinal(&sha, buffer);
- break;
- }
-
- for (i = 1; i < iterations; i++) {
- if (hashType == SHA) {
- wc_ShaUpdate(&sha, buffer, hLen);
- wc_ShaFinal(&sha, buffer);
- }
-#ifndef NO_MD5
- else {
- wc_Md5Update(&md5, buffer, hLen);
- wc_Md5Final(&md5, buffer);
- }
-#endif
- }
- XMEMCPY(output, buffer, kLen);
-
- return 0;
-}
-#endif /* NO_SHA */
-
-
-int GetDigestSize(int hashType)
-{
- int hLen;
-
- switch (hashType) {
-#ifndef NO_MD5
- case MD5:
- hLen = MD5_DIGEST_SIZE;
- break;
-#endif
-#ifndef NO_SHA
- case SHA:
- hLen = SHA_DIGEST_SIZE;
- break;
-#endif
-#ifndef NO_SHA256
- case SHA256:
- hLen = SHA256_DIGEST_SIZE;
- break;
-#endif
-#ifdef WOLFSSL_SHA512
- case SHA512:
- hLen = SHA512_DIGEST_SIZE;
- break;
-#endif
- default:
- return BAD_FUNC_ARG;
- }
-
- return hLen;
-}
-
-
-int wc_PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
- int sLen, int iterations, int kLen, int hashType)
-{
- word32 i = 1;
- int hLen;
- int j, ret;
- Hmac hmac;
-#ifdef WOLFSSL_SMALL_STACK
- byte* buffer;
-#else
- byte buffer[MAX_DIGEST_SIZE];
-#endif
-
- hLen = GetDigestSize(hashType);
- if (hLen < 0)
- return BAD_FUNC_ARG;
-
-#ifdef WOLFSSL_SMALL_STACK
- buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (buffer == NULL)
- return MEMORY_E;
-#endif
-
- ret = wc_HmacSetKey(&hmac, hashType, passwd, pLen);
-
- if (ret == 0) {
- while (kLen) {
- int currentLen;
-
- ret = wc_HmacUpdate(&hmac, salt, sLen);
- if (ret != 0)
- break;
-
- /* encode i */
- for (j = 0; j < 4; j++) {
- byte b = (byte)(i >> ((3-j) * 8));
-
- ret = wc_HmacUpdate(&hmac, &b, 1);
- if (ret != 0)
- break;
- }
-
- /* check ret from inside for loop */
- if (ret != 0)
- break;
-
- ret = wc_HmacFinal(&hmac, buffer);
- if (ret != 0)
- break;
-
- currentLen = min(kLen, hLen);
- XMEMCPY(output, buffer, currentLen);
-
- for (j = 1; j < iterations; j++) {
- ret = wc_HmacUpdate(&hmac, buffer, hLen);
- if (ret != 0)
- break;
- ret = wc_HmacFinal(&hmac, buffer);
- if (ret != 0)
- break;
- xorbuf(output, buffer, currentLen);
- }
-
- /* check ret from inside for loop */
- if (ret != 0)
- break;
-
- output += currentLen;
- kLen -= currentLen;
- i++;
- }
- }
-
-#ifdef WOLFSSL_SMALL_STACK
- XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
-#endif
-
- return ret;
-}
-
-#ifdef WOLFSSL_SHA512
- #define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE
-#elif !defined(NO_SHA256)
- #define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE
-#else
- #define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE
-#endif
-
-/* helper for wc_PKCS12_PBKDF(), sets block and digest sizes */
-int GetPKCS12HashSizes(int hashType, word32* v, word32* u)
-{
- if (!v || !u)
- return BAD_FUNC_ARG;
-
- switch (hashType) {
-#ifndef NO_MD5
- case MD5:
- *v = MD5_BLOCK_SIZE;
- *u = MD5_DIGEST_SIZE;
- break;
-#endif
-#ifndef NO_SHA
- case SHA:
- *v = SHA_BLOCK_SIZE;
- *u = SHA_DIGEST_SIZE;
- break;
-#endif
-#ifndef NO_SHA256
- case SHA256:
- *v = SHA256_BLOCK_SIZE;
- *u = SHA256_DIGEST_SIZE;
- break;
-#endif
-#ifdef WOLFSSL_SHA512
- case SHA512:
- *v = SHA512_BLOCK_SIZE;
- *u = SHA512_DIGEST_SIZE;
- break;
-#endif
- default:
- return BAD_FUNC_ARG;
- }
-
- return 0;
-}
-
-/* helper for PKCS12_PBKDF(), does hash operation */
-int DoPKCS12Hash(int hashType, byte* buffer, word32 totalLen,
- byte* Ai, word32 u, int iterations)
-{
- int i;
- int ret = 0;
-
- if (buffer == NULL || Ai == NULL)
- return BAD_FUNC_ARG;
-
- switch (hashType) {
-#ifndef NO_MD5
- case MD5:
- {
- Md5 md5;
- wc_InitMd5(&md5);
- wc_Md5Update(&md5, buffer, totalLen);
- wc_Md5Final(&md5, Ai);
-
- for (i = 1; i < iterations; i++) {
- wc_Md5Update(&md5, Ai, u);
- wc_Md5Final(&md5, Ai);
- }
- }
- break;
-#endif /* NO_MD5 */
-#ifndef NO_SHA
- case SHA:
- {
- Sha sha;
- ret = wc_InitSha(&sha);
- if (ret != 0)
- break;
- wc_ShaUpdate(&sha, buffer, totalLen);
- wc_ShaFinal(&sha, Ai);
-
- for (i = 1; i < iterations; i++) {
- wc_ShaUpdate(&sha, Ai, u);
- wc_ShaFinal(&sha, Ai);
- }
- }
- break;
-#endif /* NO_SHA */
-#ifndef NO_SHA256
- case SHA256:
- {
- Sha256 sha256;
- ret = wc_InitSha256(&sha256);
- if (ret != 0)
- break;
-
- ret = wc_Sha256Update(&sha256, buffer, totalLen);
- if (ret != 0)
- break;
-
- ret = wc_Sha256Final(&sha256, Ai);
- if (ret != 0)
- break;
-
- for (i = 1; i < iterations; i++) {
- ret = wc_Sha256Update(&sha256, Ai, u);
- if (ret != 0)
- break;
-
- ret = wc_Sha256Final(&sha256, Ai);
- if (ret != 0)
- break;
- }
- }
- break;
-#endif /* NO_SHA256 */
-#ifdef WOLFSSL_SHA512
- case SHA512:
- {
- Sha512 sha512;
- ret = wc_InitSha512(&sha512);
- if (ret != 0)
- break;
-
- ret = wc_Sha512Update(&sha512, buffer, totalLen);
- if (ret != 0)
- break;
-
- ret = wc_Sha512Final(&sha512, Ai);
- if (ret != 0)
- break;
-
- for (i = 1; i < iterations; i++) {
- ret = wc_Sha512Update(&sha512, Ai, u);
- if (ret != 0)
- break;
-
- ret = wc_Sha512Final(&sha512, Ai);
- if (ret != 0)
- break;
- }
- }
- break;
-#endif /* WOLFSSL_SHA512 */
-
- default:
- ret = BAD_FUNC_ARG;
- break;
- }
-
- return ret;
-}
-
-int wc_PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
- int saltLen, int iterations, int kLen, int hashType, int id)
-{
- /* all in bytes instead of bits */
- word32 u, v, dLen, pLen, iLen, sLen, totalLen;
- int dynamic = 0;
- int ret = 0;
- int i;
- byte *D, *S, *P, *I;
-#ifdef WOLFSSL_SMALL_STACK
- byte staticBuffer[1]; /* force dynamic usage */
-#else
- byte staticBuffer[1024];
-#endif
- byte* buffer = staticBuffer;
-
-#ifdef WOLFSSL_SMALL_STACK
- byte* Ai;
- byte* B;
-#else
- byte Ai[PBKDF_DIGEST_SIZE];
- byte B[PBKDF_DIGEST_SIZE];
-#endif
-
- if (!iterations)
- iterations = 1;
-
- ret = GetPKCS12HashSizes(hashType, &v, &u);
- if (ret < 0)
- return BAD_FUNC_ARG;
-
-#ifdef WOLFSSL_SMALL_STACK
- Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (Ai == NULL)
- return MEMORY_E;
-
- B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- if (B == NULL) {
- XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- return MEMORY_E;
- }
-#endif
-
- XMEMSET(Ai, 0, PBKDF_DIGEST_SIZE);
- XMEMSET(B, 0, PBKDF_DIGEST_SIZE);
-
- dLen = v;
- sLen = v * ((saltLen + v - 1) / v);
- if (passLen)
- pLen = v * ((passLen + v - 1) / v);
- else
- pLen = 0;
- iLen = sLen + pLen;
-
- totalLen = dLen + sLen + pLen;
-
- if (totalLen > sizeof(staticBuffer)) {
- buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY);
- if (buffer == NULL) {
-#ifdef WOLFSSL_SMALL_STACK
- XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER);
-#endif
- return MEMORY_E;
- }
- dynamic = 1;
- }
-
- D = buffer;
- S = D + dLen;
- P = S + sLen;
- I = S;
-
- XMEMSET(D, id, dLen);
-
- for (i = 0; i < (int)sLen; i++)
- S[i] = salt[i % saltLen];
- for (i = 0; i < (int)pLen; i++)
- P[i] = passwd[i % passLen];
-
- while (kLen > 0) {
- word32 currentLen;
- mp_int B1;
-
- ret = DoPKCS12Hash(hashType, buffer, totalLen, Ai, u, iterations);
- if (ret < 0)
- break;
-
- for (i = 0; i < (int)v; i++)
- B[i] = Ai[i % u];
-
- if (mp_init(&B1) != MP_OKAY)
- ret = MP_INIT_E;
- else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)
- ret = MP_READ_E;
- else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY)
- ret = MP_ADD_E;
-
- if (ret != 0) {
- mp_clear(&B1);
- break;
- }
-
- for (i = 0; i < (int)iLen; i += v) {
- int outSz;
- mp_int i1;
- mp_int res;
-
- if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) {
- ret = MP_INIT_E;
- break;
- }
- if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)
- ret = MP_READ_E;
- else if (mp_add(&i1, &B1, &res) != MP_OKAY)
- ret = MP_ADD_E;
- else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)
- ret = MP_TO_E;
- else {
- if (outSz > (int)v) {
- /* take off MSB */
- byte tmp[129];
- ret = mp_to_unsigned_bin(&res, tmp);
- XMEMCPY(I + i, tmp + 1, v);
- }
- else if (outSz < (int)v) {
- XMEMSET(I + i, 0, v - outSz);
- ret = mp_to_unsigned_bin(&res, I + i + v - outSz);
- }
- else
- ret = mp_to_unsigned_bin(&res, I + i);
- }
-
- mp_clear(&i1);
- mp_clear(&res);
- if (ret < 0) break;
- }
-
- currentLen = min(kLen, (int)u);
- XMEMCPY(output, Ai, currentLen);
- output += currentLen;
- kLen -= currentLen;
- mp_clear(&B1);
- }
-
- if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY);
-
-#ifdef WOLFSSL_SMALL_STACK
- XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER);
- XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER);
-#endif
-
- return ret;
-}
-
-#undef PBKDF_DIGEST_SIZE
-
-#endif /* NO_PWDBASED */
-
-
