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 CyaSSL by
pwdbased.c
00001 /* pwdbased.c 00002 * 00003 * Copyright (C) 2006-2014 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 00020 */ 00021 00022 #ifdef HAVE_CONFIG_H 00023 #include <config.h> 00024 #endif 00025 00026 #include <cyassl/ctaocrypt/settings.h> 00027 00028 #ifndef NO_PWDBASED 00029 00030 #ifdef CYASSL_PIC32MZ_HASH 00031 00032 #define InitMd5 InitMd5_sw 00033 #define Md5Update Md5Update_sw 00034 #define Md5Final Md5Final_sw 00035 00036 #define InitSha InitSha_sw 00037 #define ShaUpdate ShaUpdate_sw 00038 #define ShaFinal ShaFinal_sw 00039 00040 #define InitSha256 InitSha256_sw 00041 #define Sha256Update Sha256Update_sw 00042 #define Sha256Final Sha256Final_sw 00043 00044 #endif 00045 00046 #include <cyassl/ctaocrypt/pwdbased.h> 00047 #include <cyassl/ctaocrypt/hmac.h> 00048 #include <cyassl/ctaocrypt/integer.h> 00049 #include <cyassl/ctaocrypt/error-crypt.h> 00050 #if defined(CYASSL_SHA512) || defined(CYASSL_SHA384) 00051 #include <cyassl/ctaocrypt/sha512.h> 00052 #endif 00053 00054 #ifdef NO_INLINE 00055 #include <cyassl/ctaocrypt/misc.h> 00056 #else 00057 #include <ctaocrypt/src/misc.c> 00058 #endif 00059 00060 00061 #ifndef min 00062 00063 static INLINE word32 min(word32 a, word32 b) 00064 { 00065 return a > b ? b : a; 00066 } 00067 00068 #endif /* min */ 00069 00070 00071 int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, 00072 int sLen, int iterations, int kLen, int hashType) 00073 { 00074 Md5 md5; 00075 Sha sha; 00076 int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE; 00077 int i, ret = 0; 00078 byte buffer[SHA_DIGEST_SIZE]; /* max size */ 00079 00080 if (hashType != MD5 && hashType != SHA) 00081 return BAD_FUNC_ARG; 00082 00083 if (kLen > hLen) 00084 return BAD_FUNC_ARG; 00085 00086 if (iterations < 1) 00087 return BAD_FUNC_ARG; 00088 00089 if (hashType == MD5) { 00090 InitMd5(&md5); 00091 Md5Update(&md5, passwd, pLen); 00092 Md5Update(&md5, salt, sLen); 00093 Md5Final(&md5, buffer); 00094 } 00095 else { 00096 ret = InitSha(&sha); 00097 if (ret != 0) 00098 return ret; 00099 ShaUpdate(&sha, passwd, pLen); 00100 ShaUpdate(&sha, salt, sLen); 00101 ShaFinal(&sha, buffer); 00102 } 00103 00104 for (i = 1; i < iterations; i++) { 00105 if (hashType == MD5) { 00106 Md5Update(&md5, buffer, hLen); 00107 Md5Final(&md5, buffer); 00108 } 00109 else { 00110 ShaUpdate(&sha, buffer, hLen); 00111 ShaFinal(&sha, buffer); 00112 } 00113 } 00114 XMEMCPY(output, buffer, kLen); 00115 00116 return 0; 00117 } 00118 00119 00120 int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, 00121 int sLen, int iterations, int kLen, int hashType) 00122 { 00123 word32 i = 1; 00124 int hLen; 00125 int j, ret; 00126 Hmac hmac; 00127 #ifdef CYASSL_SMALL_STACK 00128 byte* buffer; 00129 #else 00130 byte buffer[MAX_DIGEST_SIZE]; 00131 #endif 00132 00133 if (hashType == MD5) { 00134 hLen = MD5_DIGEST_SIZE; 00135 } 00136 else if (hashType == SHA) { 00137 hLen = SHA_DIGEST_SIZE; 00138 } 00139 #ifndef NO_SHA256 00140 else if (hashType == SHA256) { 00141 hLen = SHA256_DIGEST_SIZE; 00142 } 00143 #endif 00144 #ifdef CYASSL_SHA512 00145 else if (hashType == SHA512) { 00146 hLen = SHA512_DIGEST_SIZE; 00147 } 00148 #endif 00149 else 00150 return BAD_FUNC_ARG; 00151 00152 #ifdef CYASSL_SMALL_STACK 00153 buffer = (byte*)XMALLOC(MAX_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00154 if (buffer == NULL) 00155 return MEMORY_E; 00156 #endif 00157 00158 ret = HmacSetKey(&hmac, hashType, passwd, pLen); 00159 00160 if (ret == 0) { 00161 while (kLen) { 00162 int currentLen; 00163 00164 ret = HmacUpdate(&hmac, salt, sLen); 00165 if (ret != 0) 00166 break; 00167 00168 /* encode i */ 00169 for (j = 0; j < 4; j++) { 00170 byte b = (byte)(i >> ((3-j) * 8)); 00171 00172 ret = HmacUpdate(&hmac, &b, 1); 00173 if (ret != 0) 00174 break; 00175 } 00176 00177 /* check ret from inside for loop */ 00178 if (ret != 0) 00179 break; 00180 00181 ret = HmacFinal(&hmac, buffer); 00182 if (ret != 0) 00183 break; 00184 00185 currentLen = min(kLen, hLen); 00186 XMEMCPY(output, buffer, currentLen); 00187 00188 for (j = 1; j < iterations; j++) { 00189 ret = HmacUpdate(&hmac, buffer, hLen); 00190 if (ret != 0) 00191 break; 00192 ret = HmacFinal(&hmac, buffer); 00193 if (ret != 0) 00194 break; 00195 xorbuf(output, buffer, currentLen); 00196 } 00197 00198 /* check ret from inside for loop */ 00199 if (ret != 0) 00200 break; 00201 00202 output += currentLen; 00203 kLen -= currentLen; 00204 i++; 00205 } 00206 } 00207 00208 #ifdef CYASSL_SMALL_STACK 00209 XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00210 #endif 00211 00212 return ret; 00213 } 00214 00215 #ifdef CYASSL_SHA512 00216 #define PBKDF_DIGEST_SIZE SHA512_BLOCK_SIZE 00217 #elif !defined(NO_SHA256) 00218 #define PBKDF_DIGEST_SIZE SHA256_BLOCK_SIZE 00219 #else 00220 #define PBKDF_DIGEST_SIZE SHA_DIGEST_SIZE 00221 #endif 00222 00223 int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, 00224 int saltLen, int iterations, int kLen, int hashType, int id) 00225 { 00226 /* all in bytes instead of bits */ 00227 word32 u, v, dLen, pLen, iLen, sLen, totalLen; 00228 int dynamic = 0; 00229 int ret = 0; 00230 int i; 00231 byte *D, *S, *P, *I; 00232 #ifdef CYASSL_SMALL_STACK 00233 byte staticBuffer[1]; /* force dynamic usage */ 00234 #else 00235 byte staticBuffer[1024]; 00236 #endif 00237 byte* buffer = staticBuffer; 00238 00239 #ifdef CYASSL_SMALL_STACK 00240 byte* Ai; 00241 byte* B; 00242 #else 00243 byte Ai[PBKDF_DIGEST_SIZE]; 00244 byte B[PBKDF_DIGEST_SIZE]; 00245 #endif 00246 00247 if (!iterations) 00248 iterations = 1; 00249 00250 if (hashType == MD5) { 00251 v = MD5_BLOCK_SIZE; 00252 u = MD5_DIGEST_SIZE; 00253 } 00254 else if (hashType == SHA) { 00255 v = SHA_BLOCK_SIZE; 00256 u = SHA_DIGEST_SIZE; 00257 } 00258 #ifndef NO_SHA256 00259 else if (hashType == SHA256) { 00260 v = SHA256_BLOCK_SIZE; 00261 u = SHA256_DIGEST_SIZE; 00262 } 00263 #endif 00264 #ifdef CYASSL_SHA512 00265 else if (hashType == SHA512) { 00266 v = SHA512_BLOCK_SIZE; 00267 u = SHA512_DIGEST_SIZE; 00268 } 00269 #endif 00270 else 00271 return BAD_FUNC_ARG; 00272 00273 #ifdef CYASSL_SMALL_STACK 00274 Ai = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00275 if (Ai == NULL) 00276 return MEMORY_E; 00277 00278 B = (byte*)XMALLOC(PBKDF_DIGEST_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00279 if (B == NULL) { 00280 XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00281 return MEMORY_E; 00282 } 00283 #endif 00284 00285 dLen = v; 00286 sLen = v * ((saltLen + v - 1) / v); 00287 if (passLen) 00288 pLen = v * ((passLen + v - 1) / v); 00289 else 00290 pLen = 0; 00291 iLen = sLen + pLen; 00292 00293 totalLen = dLen + sLen + pLen; 00294 00295 if (totalLen > sizeof(staticBuffer)) { 00296 buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY); 00297 if (buffer == NULL) { 00298 #ifdef CYASSL_SMALL_STACK 00299 XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00300 XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00301 #endif 00302 return MEMORY_E; 00303 } 00304 dynamic = 1; 00305 } 00306 00307 D = buffer; 00308 S = D + dLen; 00309 P = S + sLen; 00310 I = S; 00311 00312 XMEMSET(D, id, dLen); 00313 00314 for (i = 0; i < (int)sLen; i++) 00315 S[i] = salt[i % saltLen]; 00316 for (i = 0; i < (int)pLen; i++) 00317 P[i] = passwd[i % passLen]; 00318 00319 while (kLen > 0) { 00320 word32 currentLen; 00321 mp_int B1; 00322 00323 if (hashType == MD5) { 00324 Md5 md5; 00325 00326 InitMd5(&md5); 00327 Md5Update(&md5, buffer, totalLen); 00328 Md5Final(&md5, Ai); 00329 00330 for (i = 1; i < iterations; i++) { 00331 Md5Update(&md5, Ai, u); 00332 Md5Final(&md5, Ai); 00333 } 00334 } 00335 else if (hashType == SHA) { 00336 Sha sha; 00337 00338 ret = InitSha(&sha); 00339 if (ret != 0) 00340 break; 00341 ShaUpdate(&sha, buffer, totalLen); 00342 ShaFinal(&sha, Ai); 00343 00344 for (i = 1; i < iterations; i++) { 00345 ShaUpdate(&sha, Ai, u); 00346 ShaFinal(&sha, Ai); 00347 } 00348 } 00349 #ifndef NO_SHA256 00350 else if (hashType == SHA256) { 00351 Sha256 sha256; 00352 00353 ret = InitSha256(&sha256); 00354 if (ret != 0) 00355 break; 00356 00357 ret = Sha256Update(&sha256, buffer, totalLen); 00358 if (ret != 0) 00359 break; 00360 00361 ret = Sha256Final(&sha256, Ai); 00362 if (ret != 0) 00363 break; 00364 00365 for (i = 1; i < iterations; i++) { 00366 ret = Sha256Update(&sha256, Ai, u); 00367 if (ret != 0) 00368 break; 00369 00370 ret = Sha256Final(&sha256, Ai); 00371 if (ret != 0) 00372 break; 00373 } 00374 } 00375 #endif 00376 #ifdef CYASSL_SHA512 00377 else if (hashType == SHA512) { 00378 Sha512 sha512; 00379 00380 ret = InitSha512(&sha512); 00381 if (ret != 0) 00382 break; 00383 00384 ret = Sha512Update(&sha512, buffer, totalLen); 00385 if (ret != 0) 00386 break; 00387 00388 ret = Sha512Final(&sha512, Ai); 00389 if (ret != 0) 00390 break; 00391 00392 for (i = 1; i < iterations; i++) { 00393 ret = Sha512Update(&sha512, Ai, u); 00394 if (ret != 0) 00395 break; 00396 00397 ret = Sha512Final(&sha512, Ai); 00398 if (ret != 0) 00399 break; 00400 } 00401 } 00402 #endif 00403 00404 for (i = 0; i < (int)v; i++) 00405 B[i] = Ai[i % u]; 00406 00407 if (mp_init(&B1) != MP_OKAY) 00408 ret = MP_INIT_E; 00409 else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY) 00410 ret = MP_READ_E; 00411 else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY) 00412 ret = MP_ADD_E; 00413 00414 if (ret != 0) { 00415 mp_clear(&B1); 00416 break; 00417 } 00418 00419 for (i = 0; i < (int)iLen; i += v) { 00420 int outSz; 00421 mp_int i1; 00422 mp_int res; 00423 00424 if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) { 00425 ret = MP_INIT_E; 00426 break; 00427 } 00428 if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY) 00429 ret = MP_READ_E; 00430 else if (mp_add(&i1, &B1, &res) != MP_OKAY) 00431 ret = MP_ADD_E; 00432 else if ( (outSz = mp_unsigned_bin_size(&res)) < 0) 00433 ret = MP_TO_E; 00434 else { 00435 if (outSz > (int)v) { 00436 /* take off MSB */ 00437 byte tmp[129]; 00438 ret = mp_to_unsigned_bin(&res, tmp); 00439 XMEMCPY(I + i, tmp + 1, v); 00440 } 00441 else if (outSz < (int)v) { 00442 XMEMSET(I + i, 0, v - outSz); 00443 ret = mp_to_unsigned_bin(&res, I + i + v - outSz); 00444 } 00445 else 00446 ret = mp_to_unsigned_bin(&res, I + i); 00447 } 00448 00449 mp_clear(&i1); 00450 mp_clear(&res); 00451 if (ret < 0) break; 00452 } 00453 00454 currentLen = min(kLen, (int)u); 00455 XMEMCPY(output, Ai, currentLen); 00456 output += currentLen; 00457 kLen -= currentLen; 00458 mp_clear(&B1); 00459 } 00460 00461 if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY); 00462 00463 #ifdef CYASSL_SMALL_STACK 00464 XFREE(Ai, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00465 XFREE(B, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00466 #endif 00467 00468 return ret; 00469 } 00470 00471 #undef PBKDF_DIGEST_SIZE 00472 00473 #endif /* NO_PWDBASED */ 00474 00475
Generated on Tue Jul 12 2022 21:40:05 by
1.7.2
