A library for setting up Secure Socket Layer (SSL) connections and verifying remote hosts using certificates. Contains only the source files for mbed platform implementation of the library.
Dependents: HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL HTTPClient-SSL
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
Generated on Wed Jul 13 2022 02:33:57 by 1.7.2