This is a port of cyaSSL 2.7.0.

Dependents:   CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet

Committer:
ashleymills
Date:
Thu Sep 05 10:33:04 2013 +0000
Revision:
0:714293de3836
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:714293de3836 1 /* pwdbased.c
ashleymills 0:714293de3836 2 *
ashleymills 0:714293de3836 3 * Copyright (C) 2006-2013 wolfSSL Inc.
ashleymills 0:714293de3836 4 *
ashleymills 0:714293de3836 5 * This file is part of CyaSSL.
ashleymills 0:714293de3836 6 *
ashleymills 0:714293de3836 7 * CyaSSL is free software; you can redistribute it and/or modify
ashleymills 0:714293de3836 8 * it under the terms of the GNU General Public License as published by
ashleymills 0:714293de3836 9 * the Free Software Foundation; either version 2 of the License, or
ashleymills 0:714293de3836 10 * (at your option) any later version.
ashleymills 0:714293de3836 11 *
ashleymills 0:714293de3836 12 * CyaSSL is distributed in the hope that it will be useful,
ashleymills 0:714293de3836 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ashleymills 0:714293de3836 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ashleymills 0:714293de3836 15 * GNU General Public License for more details.
ashleymills 0:714293de3836 16 *
ashleymills 0:714293de3836 17 * You should have received a copy of the GNU General Public License
ashleymills 0:714293de3836 18 * along with this program; if not, write to the Free Software
ashleymills 0:714293de3836 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
ashleymills 0:714293de3836 20 */
ashleymills 0:714293de3836 21
ashleymills 0:714293de3836 22 #ifdef HAVE_CONFIG_H
ashleymills 0:714293de3836 23 #include <config.h>
ashleymills 0:714293de3836 24 #endif
ashleymills 0:714293de3836 25
ashleymills 0:714293de3836 26 #include <cyassl/ctaocrypt/settings.h>
ashleymills 0:714293de3836 27
ashleymills 0:714293de3836 28 #ifndef NO_PWDBASED
ashleymills 0:714293de3836 29
ashleymills 0:714293de3836 30 #include <cyassl/ctaocrypt/pwdbased.h>
ashleymills 0:714293de3836 31 #include <cyassl/ctaocrypt/hmac.h>
ashleymills 0:714293de3836 32 #include <cyassl/ctaocrypt/integer.h>
ashleymills 0:714293de3836 33 #include <cyassl/ctaocrypt/ctaoerror2.h>
ashleymills 0:714293de3836 34 #if defined(CYASSL_SHA512) || defined(CYASSL_SHA384)
ashleymills 0:714293de3836 35 #include <cyassl/ctaocrypt/sha512.h>
ashleymills 0:714293de3836 36 #endif
ashleymills 0:714293de3836 37
ashleymills 0:714293de3836 38 #ifdef NO_INLINE
ashleymills 0:714293de3836 39 #include <cyassl/ctaocrypt/misc.h>
ashleymills 0:714293de3836 40 #else
ashleymills 0:714293de3836 41 #include <ctaocrypt/src/misc.c>
ashleymills 0:714293de3836 42 #endif
ashleymills 0:714293de3836 43
ashleymills 0:714293de3836 44
ashleymills 0:714293de3836 45 #ifndef min
ashleymills 0:714293de3836 46
ashleymills 0:714293de3836 47 static INLINE word32 min(word32 a, word32 b)
ashleymills 0:714293de3836 48 {
ashleymills 0:714293de3836 49 return a > b ? b : a;
ashleymills 0:714293de3836 50 }
ashleymills 0:714293de3836 51
ashleymills 0:714293de3836 52 #endif /* min */
ashleymills 0:714293de3836 53
ashleymills 0:714293de3836 54
ashleymills 0:714293de3836 55 int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt,
ashleymills 0:714293de3836 56 int sLen, int iterations, int kLen, int hashType)
ashleymills 0:714293de3836 57 {
ashleymills 0:714293de3836 58 Md5 md5;
ashleymills 0:714293de3836 59 Sha sha;
ashleymills 0:714293de3836 60 int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 61 int i;
ashleymills 0:714293de3836 62 byte buffer[SHA_DIGEST_SIZE]; /* max size */
ashleymills 0:714293de3836 63
ashleymills 0:714293de3836 64 if (hashType != MD5 && hashType != SHA)
ashleymills 0:714293de3836 65 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 66
ashleymills 0:714293de3836 67 if (kLen > hLen)
ashleymills 0:714293de3836 68 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 69
ashleymills 0:714293de3836 70 if (iterations < 1)
ashleymills 0:714293de3836 71 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 72
ashleymills 0:714293de3836 73 if (hashType == MD5) {
ashleymills 0:714293de3836 74 InitMd5(&md5);
ashleymills 0:714293de3836 75 Md5Update(&md5, passwd, pLen);
ashleymills 0:714293de3836 76 Md5Update(&md5, salt, sLen);
ashleymills 0:714293de3836 77 Md5Final(&md5, buffer);
ashleymills 0:714293de3836 78 }
ashleymills 0:714293de3836 79 else {
ashleymills 0:714293de3836 80 InitSha(&sha);
ashleymills 0:714293de3836 81 ShaUpdate(&sha, passwd, pLen);
ashleymills 0:714293de3836 82 ShaUpdate(&sha, salt, sLen);
ashleymills 0:714293de3836 83 ShaFinal(&sha, buffer);
ashleymills 0:714293de3836 84 }
ashleymills 0:714293de3836 85
ashleymills 0:714293de3836 86 for (i = 1; i < iterations; i++) {
ashleymills 0:714293de3836 87 if (hashType == MD5) {
ashleymills 0:714293de3836 88 Md5Update(&md5, buffer, hLen);
ashleymills 0:714293de3836 89 Md5Final(&md5, buffer);
ashleymills 0:714293de3836 90 }
ashleymills 0:714293de3836 91 else {
ashleymills 0:714293de3836 92 ShaUpdate(&sha, buffer, hLen);
ashleymills 0:714293de3836 93 ShaFinal(&sha, buffer);
ashleymills 0:714293de3836 94 }
ashleymills 0:714293de3836 95 }
ashleymills 0:714293de3836 96 XMEMCPY(output, buffer, kLen);
ashleymills 0:714293de3836 97
ashleymills 0:714293de3836 98 return 0;
ashleymills 0:714293de3836 99 }
ashleymills 0:714293de3836 100
ashleymills 0:714293de3836 101
ashleymills 0:714293de3836 102 int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt,
ashleymills 0:714293de3836 103 int sLen, int iterations, int kLen, int hashType)
ashleymills 0:714293de3836 104 {
ashleymills 0:714293de3836 105 word32 i = 1;
ashleymills 0:714293de3836 106 int hLen;
ashleymills 0:714293de3836 107 int j;
ashleymills 0:714293de3836 108 Hmac hmac;
ashleymills 0:714293de3836 109 #ifdef CYASSL_SHA512
ashleymills 0:714293de3836 110 byte buffer[SHA512_DIGEST_SIZE];
ashleymills 0:714293de3836 111 #else
ashleymills 0:714293de3836 112 byte buffer[INNER_HASH_SIZE]; /* max size, doesn't handle 512 yet */
ashleymills 0:714293de3836 113 #endif
ashleymills 0:714293de3836 114
ashleymills 0:714293de3836 115 if (hashType == MD5) {
ashleymills 0:714293de3836 116 hLen = MD5_DIGEST_SIZE;
ashleymills 0:714293de3836 117 }
ashleymills 0:714293de3836 118 else if (hashType == SHA) {
ashleymills 0:714293de3836 119 hLen = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 120 }
ashleymills 0:714293de3836 121 #ifndef NO_SHA256
ashleymills 0:714293de3836 122 else if (hashType == SHA256) {
ashleymills 0:714293de3836 123 hLen = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 124 }
ashleymills 0:714293de3836 125 #endif
ashleymills 0:714293de3836 126 #ifdef CYASSL_SHA512
ashleymills 0:714293de3836 127 else if (hashType == SHA512) {
ashleymills 0:714293de3836 128 hLen = SHA512_DIGEST_SIZE;
ashleymills 0:714293de3836 129 }
ashleymills 0:714293de3836 130 #endif
ashleymills 0:714293de3836 131 else
ashleymills 0:714293de3836 132 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 133
ashleymills 0:714293de3836 134 HmacSetKey(&hmac, hashType, passwd, pLen);
ashleymills 0:714293de3836 135
ashleymills 0:714293de3836 136 while (kLen) {
ashleymills 0:714293de3836 137 int currentLen;
ashleymills 0:714293de3836 138 HmacUpdate(&hmac, salt, sLen);
ashleymills 0:714293de3836 139
ashleymills 0:714293de3836 140 /* encode i */
ashleymills 0:714293de3836 141 for (j = 0; j < 4; j++) {
ashleymills 0:714293de3836 142 byte b = (byte)(i >> ((3-j) * 8));
ashleymills 0:714293de3836 143 HmacUpdate(&hmac, &b, 1);
ashleymills 0:714293de3836 144 }
ashleymills 0:714293de3836 145 HmacFinal(&hmac, buffer);
ashleymills 0:714293de3836 146
ashleymills 0:714293de3836 147 currentLen = min(kLen, hLen);
ashleymills 0:714293de3836 148 XMEMCPY(output, buffer, currentLen);
ashleymills 0:714293de3836 149
ashleymills 0:714293de3836 150 for (j = 1; j < iterations; j++) {
ashleymills 0:714293de3836 151 HmacUpdate(&hmac, buffer, hLen);
ashleymills 0:714293de3836 152 HmacFinal(&hmac, buffer);
ashleymills 0:714293de3836 153 xorbuf(output, buffer, currentLen);
ashleymills 0:714293de3836 154 }
ashleymills 0:714293de3836 155
ashleymills 0:714293de3836 156 output += currentLen;
ashleymills 0:714293de3836 157 kLen -= currentLen;
ashleymills 0:714293de3836 158 i++;
ashleymills 0:714293de3836 159 }
ashleymills 0:714293de3836 160
ashleymills 0:714293de3836 161 return 0;
ashleymills 0:714293de3836 162 }
ashleymills 0:714293de3836 163
ashleymills 0:714293de3836 164
ashleymills 0:714293de3836 165 int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt,
ashleymills 0:714293de3836 166 int saltLen, int iterations, int kLen, int hashType, int id)
ashleymills 0:714293de3836 167 {
ashleymills 0:714293de3836 168 /* all in bytes instead of bits */
ashleymills 0:714293de3836 169 word32 u, v, dLen, pLen, iLen, sLen, totalLen;
ashleymills 0:714293de3836 170 int dynamic = 0;
ashleymills 0:714293de3836 171 int ret = 0;
ashleymills 0:714293de3836 172 int i;
ashleymills 0:714293de3836 173 byte *D, *S, *P, *I;
ashleymills 0:714293de3836 174 byte staticBuffer[1024];
ashleymills 0:714293de3836 175 byte* buffer = staticBuffer;
ashleymills 0:714293de3836 176 #ifdef CYASSL_SHA512
ashleymills 0:714293de3836 177 byte Ai[SHA512_DIGEST_SIZE];
ashleymills 0:714293de3836 178 byte B[SHA512_BLOCK_SIZE];
ashleymills 0:714293de3836 179 #elif !defined(NO_SHA256)
ashleymills 0:714293de3836 180 byte Ai[SHA256_DIGEST_SIZE];
ashleymills 0:714293de3836 181 byte B[SHA256_BLOCK_SIZE];
ashleymills 0:714293de3836 182 #else
ashleymills 0:714293de3836 183 byte Ai[SHA_DIGEST_SIZE];
ashleymills 0:714293de3836 184 byte B[SHA_BLOCK_SIZE];
ashleymills 0:714293de3836 185 #endif
ashleymills 0:714293de3836 186
ashleymills 0:714293de3836 187 if (!iterations)
ashleymills 0:714293de3836 188 iterations = 1;
ashleymills 0:714293de3836 189
ashleymills 0:714293de3836 190 if (hashType == MD5) {
ashleymills 0:714293de3836 191 v = MD5_BLOCK_SIZE;
ashleymills 0:714293de3836 192 u = MD5_DIGEST_SIZE;
ashleymills 0:714293de3836 193 }
ashleymills 0:714293de3836 194 else if (hashType == SHA) {
ashleymills 0:714293de3836 195 v = SHA_BLOCK_SIZE;
ashleymills 0:714293de3836 196 u = SHA_DIGEST_SIZE;
ashleymills 0:714293de3836 197 }
ashleymills 0:714293de3836 198 #ifndef NO_SHA256
ashleymills 0:714293de3836 199 else if (hashType == SHA256) {
ashleymills 0:714293de3836 200 v = SHA256_BLOCK_SIZE;
ashleymills 0:714293de3836 201 u = SHA256_DIGEST_SIZE;
ashleymills 0:714293de3836 202 }
ashleymills 0:714293de3836 203 #endif
ashleymills 0:714293de3836 204 #ifdef CYASSL_SHA512
ashleymills 0:714293de3836 205 else if (hashType == SHA512) {
ashleymills 0:714293de3836 206 v = SHA512_BLOCK_SIZE;
ashleymills 0:714293de3836 207 u = SHA512_DIGEST_SIZE;
ashleymills 0:714293de3836 208 }
ashleymills 0:714293de3836 209 #endif
ashleymills 0:714293de3836 210 else
ashleymills 0:714293de3836 211 return BAD_FUNC_ARG;
ashleymills 0:714293de3836 212
ashleymills 0:714293de3836 213 dLen = v;
ashleymills 0:714293de3836 214 sLen = v * ((saltLen + v - 1) / v);
ashleymills 0:714293de3836 215 if (passLen)
ashleymills 0:714293de3836 216 pLen = v * ((passLen + v - 1) / v);
ashleymills 0:714293de3836 217 else
ashleymills 0:714293de3836 218 pLen = 0;
ashleymills 0:714293de3836 219 iLen = sLen + pLen;
ashleymills 0:714293de3836 220
ashleymills 0:714293de3836 221 totalLen = dLen + sLen + pLen;
ashleymills 0:714293de3836 222
ashleymills 0:714293de3836 223 if (totalLen > sizeof(staticBuffer)) {
ashleymills 0:714293de3836 224 buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY);
ashleymills 0:714293de3836 225 if (buffer == NULL) return MEMORY_E;
ashleymills 0:714293de3836 226 dynamic = 1;
ashleymills 0:714293de3836 227 }
ashleymills 0:714293de3836 228
ashleymills 0:714293de3836 229 D = buffer;
ashleymills 0:714293de3836 230 S = D + dLen;
ashleymills 0:714293de3836 231 P = S + sLen;
ashleymills 0:714293de3836 232 I = S;
ashleymills 0:714293de3836 233
ashleymills 0:714293de3836 234 XMEMSET(D, id, dLen);
ashleymills 0:714293de3836 235
ashleymills 0:714293de3836 236 for (i = 0; i < (int)sLen; i++)
ashleymills 0:714293de3836 237 S[i] = salt[i % saltLen];
ashleymills 0:714293de3836 238 for (i = 0; i < (int)pLen; i++)
ashleymills 0:714293de3836 239 P[i] = passwd[i % passLen];
ashleymills 0:714293de3836 240
ashleymills 0:714293de3836 241 while (kLen > 0) {
ashleymills 0:714293de3836 242 word32 currentLen;
ashleymills 0:714293de3836 243 mp_int B1;
ashleymills 0:714293de3836 244
ashleymills 0:714293de3836 245 if (hashType == MD5) {
ashleymills 0:714293de3836 246 Md5 md5;
ashleymills 0:714293de3836 247
ashleymills 0:714293de3836 248 InitMd5(&md5);
ashleymills 0:714293de3836 249 Md5Update(&md5, buffer, totalLen);
ashleymills 0:714293de3836 250 Md5Final(&md5, Ai);
ashleymills 0:714293de3836 251
ashleymills 0:714293de3836 252 for (i = 1; i < iterations; i++) {
ashleymills 0:714293de3836 253 Md5Update(&md5, Ai, u);
ashleymills 0:714293de3836 254 Md5Final(&md5, Ai);
ashleymills 0:714293de3836 255 }
ashleymills 0:714293de3836 256 }
ashleymills 0:714293de3836 257 else if (hashType == SHA) {
ashleymills 0:714293de3836 258 Sha sha;
ashleymills 0:714293de3836 259
ashleymills 0:714293de3836 260 InitSha(&sha);
ashleymills 0:714293de3836 261 ShaUpdate(&sha, buffer, totalLen);
ashleymills 0:714293de3836 262 ShaFinal(&sha, Ai);
ashleymills 0:714293de3836 263
ashleymills 0:714293de3836 264 for (i = 1; i < iterations; i++) {
ashleymills 0:714293de3836 265 ShaUpdate(&sha, Ai, u);
ashleymills 0:714293de3836 266 ShaFinal(&sha, Ai);
ashleymills 0:714293de3836 267 }
ashleymills 0:714293de3836 268 }
ashleymills 0:714293de3836 269 #ifndef NO_SHA256
ashleymills 0:714293de3836 270 else if (hashType == SHA256) {
ashleymills 0:714293de3836 271 Sha256 sha256;
ashleymills 0:714293de3836 272
ashleymills 0:714293de3836 273 InitSha256(&sha256);
ashleymills 0:714293de3836 274 Sha256Update(&sha256, buffer, totalLen);
ashleymills 0:714293de3836 275 Sha256Final(&sha256, Ai);
ashleymills 0:714293de3836 276
ashleymills 0:714293de3836 277 for (i = 1; i < iterations; i++) {
ashleymills 0:714293de3836 278 Sha256Update(&sha256, Ai, u);
ashleymills 0:714293de3836 279 Sha256Final(&sha256, Ai);
ashleymills 0:714293de3836 280 }
ashleymills 0:714293de3836 281 }
ashleymills 0:714293de3836 282 #endif
ashleymills 0:714293de3836 283 #ifdef CYASSL_SHA512
ashleymills 0:714293de3836 284 else if (hashType == SHA512) {
ashleymills 0:714293de3836 285 Sha512 sha512;
ashleymills 0:714293de3836 286
ashleymills 0:714293de3836 287 InitSha512(&sha512);
ashleymills 0:714293de3836 288 Sha512Update(&sha512, buffer, totalLen);
ashleymills 0:714293de3836 289 Sha512Final(&sha512, Ai);
ashleymills 0:714293de3836 290
ashleymills 0:714293de3836 291 for (i = 1; i < iterations; i++) {
ashleymills 0:714293de3836 292 Sha512Update(&sha512, Ai, u);
ashleymills 0:714293de3836 293 Sha512Final(&sha512, Ai);
ashleymills 0:714293de3836 294 }
ashleymills 0:714293de3836 295 }
ashleymills 0:714293de3836 296 #endif
ashleymills 0:714293de3836 297
ashleymills 0:714293de3836 298 for (i = 0; i < (int)v; i++)
ashleymills 0:714293de3836 299 B[i] = Ai[i % u];
ashleymills 0:714293de3836 300
ashleymills 0:714293de3836 301 if (mp_init(&B1) != MP_OKAY)
ashleymills 0:714293de3836 302 ret = MP_INIT_E;
ashleymills 0:714293de3836 303 else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY)
ashleymills 0:714293de3836 304 ret = MP_READ_E;
ashleymills 0:714293de3836 305 else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY)
ashleymills 0:714293de3836 306 ret = MP_ADD_E;
ashleymills 0:714293de3836 307
ashleymills 0:714293de3836 308 if (ret != 0) {
ashleymills 0:714293de3836 309 mp_clear(&B1);
ashleymills 0:714293de3836 310 break;
ashleymills 0:714293de3836 311 }
ashleymills 0:714293de3836 312
ashleymills 0:714293de3836 313 for (i = 0; i < (int)iLen; i += v) {
ashleymills 0:714293de3836 314 int outSz;
ashleymills 0:714293de3836 315 mp_int i1;
ashleymills 0:714293de3836 316 mp_int res;
ashleymills 0:714293de3836 317
ashleymills 0:714293de3836 318 if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) {
ashleymills 0:714293de3836 319 ret = MP_INIT_E;
ashleymills 0:714293de3836 320 break;
ashleymills 0:714293de3836 321 }
ashleymills 0:714293de3836 322 if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY)
ashleymills 0:714293de3836 323 ret = MP_READ_E;
ashleymills 0:714293de3836 324 else if (mp_add(&i1, &B1, &res) != MP_OKAY)
ashleymills 0:714293de3836 325 ret = MP_ADD_E;
ashleymills 0:714293de3836 326 else if ( (outSz = mp_unsigned_bin_size(&res)) < 0)
ashleymills 0:714293de3836 327 ret = MP_TO_E;
ashleymills 0:714293de3836 328 else {
ashleymills 0:714293de3836 329 if (outSz > (int)v) {
ashleymills 0:714293de3836 330 /* take off MSB */
ashleymills 0:714293de3836 331 byte tmp[129];
ashleymills 0:714293de3836 332 mp_to_unsigned_bin(&res, tmp);
ashleymills 0:714293de3836 333 XMEMCPY(I + i, tmp + 1, v);
ashleymills 0:714293de3836 334 }
ashleymills 0:714293de3836 335 else if (outSz < (int)v) {
ashleymills 0:714293de3836 336 XMEMSET(I + i, 0, v - outSz);
ashleymills 0:714293de3836 337 mp_to_unsigned_bin(&res, I + i + v - outSz);
ashleymills 0:714293de3836 338 }
ashleymills 0:714293de3836 339 else
ashleymills 0:714293de3836 340 mp_to_unsigned_bin(&res, I + i);
ashleymills 0:714293de3836 341 }
ashleymills 0:714293de3836 342
ashleymills 0:714293de3836 343 mp_clear(&i1);
ashleymills 0:714293de3836 344 mp_clear(&res);
ashleymills 0:714293de3836 345 if (ret < 0) break;
ashleymills 0:714293de3836 346 }
ashleymills 0:714293de3836 347
ashleymills 0:714293de3836 348 currentLen = min(kLen, (int)u);
ashleymills 0:714293de3836 349 XMEMCPY(output, Ai, currentLen);
ashleymills 0:714293de3836 350 output += currentLen;
ashleymills 0:714293de3836 351 kLen -= currentLen;
ashleymills 0:714293de3836 352 mp_clear(&B1);
ashleymills 0:714293de3836 353 }
ashleymills 0:714293de3836 354
ashleymills 0:714293de3836 355 if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY);
ashleymills 0:714293de3836 356 return ret;
ashleymills 0:714293de3836 357 }
ashleymills 0:714293de3836 358
ashleymills 0:714293de3836 359 #endif /* NO_PWDBASED */
ashleymills 0:714293de3836 360