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.
pwdbased.c
00001 /* pwdbased.c 00002 * 00003 * Copyright (C) 2006-2013 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 byte buffer[MAX_DIGEST_SIZE]; 00128 00129 if (hashType == MD5) { 00130 hLen = MD5_DIGEST_SIZE; 00131 } 00132 else if (hashType == SHA) { 00133 hLen = SHA_DIGEST_SIZE; 00134 } 00135 #ifndef NO_SHA256 00136 else if (hashType == SHA256) { 00137 hLen = SHA256_DIGEST_SIZE; 00138 } 00139 #endif 00140 #ifdef CYASSL_SHA512 00141 else if (hashType == SHA512) { 00142 hLen = SHA512_DIGEST_SIZE; 00143 } 00144 #endif 00145 else 00146 return BAD_FUNC_ARG; 00147 00148 ret = HmacSetKey(&hmac, hashType, passwd, pLen); 00149 if (ret != 0) 00150 return ret; 00151 00152 while (kLen) { 00153 int currentLen; 00154 HmacUpdate(&hmac, salt, sLen); 00155 00156 /* encode i */ 00157 for (j = 0; j < 4; j++) { 00158 byte b = (byte)(i >> ((3-j) * 8)); 00159 HmacUpdate(&hmac, &b, 1); 00160 } 00161 HmacFinal(&hmac, buffer); 00162 00163 currentLen = min(kLen, hLen); 00164 XMEMCPY(output, buffer, currentLen); 00165 00166 for (j = 1; j < iterations; j++) { 00167 HmacUpdate(&hmac, buffer, hLen); 00168 HmacFinal(&hmac, buffer); 00169 xorbuf(output, buffer, currentLen); 00170 } 00171 00172 output += currentLen; 00173 kLen -= currentLen; 00174 i++; 00175 } 00176 00177 return 0; 00178 } 00179 00180 00181 int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, 00182 int saltLen, int iterations, int kLen, int hashType, int id) 00183 { 00184 /* all in bytes instead of bits */ 00185 word32 u, v, dLen, pLen, iLen, sLen, totalLen; 00186 int dynamic = 0; 00187 int ret = 0; 00188 int i; 00189 byte *D, *S, *P, *I; 00190 byte staticBuffer[1024]; 00191 byte* buffer = staticBuffer; 00192 #ifdef CYASSL_SHA512 00193 byte Ai[SHA512_DIGEST_SIZE]; 00194 byte B[SHA512_BLOCK_SIZE]; 00195 #elif !defined(NO_SHA256) 00196 byte Ai[SHA256_DIGEST_SIZE]; 00197 byte B[SHA256_BLOCK_SIZE]; 00198 #else 00199 byte Ai[SHA_DIGEST_SIZE]; 00200 byte B[SHA_BLOCK_SIZE]; 00201 #endif 00202 00203 if (!iterations) 00204 iterations = 1; 00205 00206 if (hashType == MD5) { 00207 v = MD5_BLOCK_SIZE; 00208 u = MD5_DIGEST_SIZE; 00209 } 00210 else if (hashType == SHA) { 00211 v = SHA_BLOCK_SIZE; 00212 u = SHA_DIGEST_SIZE; 00213 } 00214 #ifndef NO_SHA256 00215 else if (hashType == SHA256) { 00216 v = SHA256_BLOCK_SIZE; 00217 u = SHA256_DIGEST_SIZE; 00218 } 00219 #endif 00220 #ifdef CYASSL_SHA512 00221 else if (hashType == SHA512) { 00222 v = SHA512_BLOCK_SIZE; 00223 u = SHA512_DIGEST_SIZE; 00224 } 00225 #endif 00226 else 00227 return BAD_FUNC_ARG; 00228 00229 dLen = v; 00230 sLen = v * ((saltLen + v - 1) / v); 00231 if (passLen) 00232 pLen = v * ((passLen + v - 1) / v); 00233 else 00234 pLen = 0; 00235 iLen = sLen + pLen; 00236 00237 totalLen = dLen + sLen + pLen; 00238 00239 if (totalLen > sizeof(staticBuffer)) { 00240 buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY); 00241 if (buffer == NULL) return MEMORY_E; 00242 dynamic = 1; 00243 } 00244 00245 D = buffer; 00246 S = D + dLen; 00247 P = S + sLen; 00248 I = S; 00249 00250 XMEMSET(D, id, dLen); 00251 00252 for (i = 0; i < (int)sLen; i++) 00253 S[i] = salt[i % saltLen]; 00254 for (i = 0; i < (int)pLen; i++) 00255 P[i] = passwd[i % passLen]; 00256 00257 while (kLen > 0) { 00258 word32 currentLen; 00259 mp_int B1; 00260 00261 if (hashType == MD5) { 00262 Md5 md5; 00263 00264 InitMd5(&md5); 00265 Md5Update(&md5, buffer, totalLen); 00266 Md5Final(&md5, Ai); 00267 00268 for (i = 1; i < iterations; i++) { 00269 Md5Update(&md5, Ai, u); 00270 Md5Final(&md5, Ai); 00271 } 00272 } 00273 else if (hashType == SHA) { 00274 Sha sha; 00275 00276 ret = InitSha(&sha); 00277 if (ret != 0) 00278 break; 00279 ShaUpdate(&sha, buffer, totalLen); 00280 ShaFinal(&sha, Ai); 00281 00282 for (i = 1; i < iterations; i++) { 00283 ShaUpdate(&sha, Ai, u); 00284 ShaFinal(&sha, Ai); 00285 } 00286 } 00287 #ifndef NO_SHA256 00288 else if (hashType == SHA256) { 00289 Sha256 sha256; 00290 00291 ret = InitSha256(&sha256); 00292 if (ret != 0) 00293 break; 00294 Sha256Update(&sha256, buffer, totalLen); 00295 Sha256Final(&sha256, Ai); 00296 00297 for (i = 1; i < iterations; i++) { 00298 Sha256Update(&sha256, Ai, u); 00299 Sha256Final(&sha256, Ai); 00300 } 00301 } 00302 #endif 00303 #ifdef CYASSL_SHA512 00304 else if (hashType == SHA512) { 00305 Sha512 sha512; 00306 00307 ret = InitSha512(&sha512); 00308 if (ret != 0) 00309 break; 00310 Sha512Update(&sha512, buffer, totalLen); 00311 Sha512Final(&sha512, Ai); 00312 00313 for (i = 1; i < iterations; i++) { 00314 Sha512Update(&sha512, Ai, u); 00315 Sha512Final(&sha512, Ai); 00316 } 00317 } 00318 #endif 00319 00320 for (i = 0; i < (int)v; i++) 00321 B[i] = Ai[i % u]; 00322 00323 if (mp_init(&B1) != MP_OKAY) 00324 ret = MP_INIT_E; 00325 else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY) 00326 ret = MP_READ_E; 00327 else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY) 00328 ret = MP_ADD_E; 00329 00330 if (ret != 0) { 00331 mp_clear(&B1); 00332 break; 00333 } 00334 00335 for (i = 0; i < (int)iLen; i += v) { 00336 int outSz; 00337 mp_int i1; 00338 mp_int res; 00339 00340 if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) { 00341 ret = MP_INIT_E; 00342 break; 00343 } 00344 if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY) 00345 ret = MP_READ_E; 00346 else if (mp_add(&i1, &B1, &res) != MP_OKAY) 00347 ret = MP_ADD_E; 00348 else if ( (outSz = mp_unsigned_bin_size(&res)) < 0) 00349 ret = MP_TO_E; 00350 else { 00351 if (outSz > (int)v) { 00352 /* take off MSB */ 00353 byte tmp[129]; 00354 ret = mp_to_unsigned_bin(&res, tmp); 00355 XMEMCPY(I + i, tmp + 1, v); 00356 } 00357 else if (outSz < (int)v) { 00358 XMEMSET(I + i, 0, v - outSz); 00359 ret = mp_to_unsigned_bin(&res, I + i + v - outSz); 00360 } 00361 else 00362 ret = mp_to_unsigned_bin(&res, I + i); 00363 } 00364 00365 mp_clear(&i1); 00366 mp_clear(&res); 00367 if (ret < 0) break; 00368 } 00369 00370 currentLen = min(kLen, (int)u); 00371 XMEMCPY(output, Ai, currentLen); 00372 output += currentLen; 00373 kLen -= currentLen; 00374 mp_clear(&B1); 00375 } 00376 00377 if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY); 00378 return ret; 00379 } 00380 00381 #endif /* NO_PWDBASED */ 00382
Generated on Tue Jul 12 2022 20:12:51 by
