This is a port of cyaSSL 2.7.0.
Dependents: CyaSSL_DTLS_Cellular CyaSSL_DTLS_Ethernet
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 #include <cyassl/ctaocrypt/pwdbased.h> 00031 #include <cyassl/ctaocrypt/hmac.h> 00032 #include <cyassl/ctaocrypt/integer.h> 00033 #include <cyassl/ctaocrypt/ctaoerror2.h> 00034 #if defined(CYASSL_SHA512) || defined(CYASSL_SHA384) 00035 #include <cyassl/ctaocrypt/sha512.h> 00036 #endif 00037 00038 #ifdef NO_INLINE 00039 #include <cyassl/ctaocrypt/misc.h> 00040 #else 00041 #include <ctaocrypt/src/misc.c> 00042 #endif 00043 00044 00045 #ifndef min 00046 00047 static INLINE word32 min(word32 a, word32 b) 00048 { 00049 return a > b ? b : a; 00050 } 00051 00052 #endif /* min */ 00053 00054 00055 int PBKDF1(byte* output, const byte* passwd, int pLen, const byte* salt, 00056 int sLen, int iterations, int kLen, int hashType) 00057 { 00058 Md5 md5; 00059 Sha sha; 00060 int hLen = (hashType == MD5) ? (int)MD5_DIGEST_SIZE : (int)SHA_DIGEST_SIZE; 00061 int i; 00062 byte buffer[SHA_DIGEST_SIZE]; /* max size */ 00063 00064 if (hashType != MD5 && hashType != SHA) 00065 return BAD_FUNC_ARG; 00066 00067 if (kLen > hLen) 00068 return BAD_FUNC_ARG; 00069 00070 if (iterations < 1) 00071 return BAD_FUNC_ARG; 00072 00073 if (hashType == MD5) { 00074 InitMd5(&md5); 00075 Md5Update(&md5, passwd, pLen); 00076 Md5Update(&md5, salt, sLen); 00077 Md5Final(&md5, buffer); 00078 } 00079 else { 00080 InitSha(&sha); 00081 ShaUpdate(&sha, passwd, pLen); 00082 ShaUpdate(&sha, salt, sLen); 00083 ShaFinal(&sha, buffer); 00084 } 00085 00086 for (i = 1; i < iterations; i++) { 00087 if (hashType == MD5) { 00088 Md5Update(&md5, buffer, hLen); 00089 Md5Final(&md5, buffer); 00090 } 00091 else { 00092 ShaUpdate(&sha, buffer, hLen); 00093 ShaFinal(&sha, buffer); 00094 } 00095 } 00096 XMEMCPY(output, buffer, kLen); 00097 00098 return 0; 00099 } 00100 00101 00102 int PBKDF2(byte* output, const byte* passwd, int pLen, const byte* salt, 00103 int sLen, int iterations, int kLen, int hashType) 00104 { 00105 word32 i = 1; 00106 int hLen; 00107 int j; 00108 Hmac hmac; 00109 #ifdef CYASSL_SHA512 00110 byte buffer[SHA512_DIGEST_SIZE]; 00111 #else 00112 byte buffer[INNER_HASH_SIZE]; /* max size, doesn't handle 512 yet */ 00113 #endif 00114 00115 if (hashType == MD5) { 00116 hLen = MD5_DIGEST_SIZE; 00117 } 00118 else if (hashType == SHA) { 00119 hLen = SHA_DIGEST_SIZE; 00120 } 00121 #ifndef NO_SHA256 00122 else if (hashType == SHA256) { 00123 hLen = SHA256_DIGEST_SIZE; 00124 } 00125 #endif 00126 #ifdef CYASSL_SHA512 00127 else if (hashType == SHA512) { 00128 hLen = SHA512_DIGEST_SIZE; 00129 } 00130 #endif 00131 else 00132 return BAD_FUNC_ARG; 00133 00134 HmacSetKey(&hmac, hashType, passwd, pLen); 00135 00136 while (kLen) { 00137 int currentLen; 00138 HmacUpdate(&hmac, salt, sLen); 00139 00140 /* encode i */ 00141 for (j = 0; j < 4; j++) { 00142 byte b = (byte)(i >> ((3-j) * 8)); 00143 HmacUpdate(&hmac, &b, 1); 00144 } 00145 HmacFinal(&hmac, buffer); 00146 00147 currentLen = min(kLen, hLen); 00148 XMEMCPY(output, buffer, currentLen); 00149 00150 for (j = 1; j < iterations; j++) { 00151 HmacUpdate(&hmac, buffer, hLen); 00152 HmacFinal(&hmac, buffer); 00153 xorbuf(output, buffer, currentLen); 00154 } 00155 00156 output += currentLen; 00157 kLen -= currentLen; 00158 i++; 00159 } 00160 00161 return 0; 00162 } 00163 00164 00165 int PKCS12_PBKDF(byte* output, const byte* passwd, int passLen,const byte* salt, 00166 int saltLen, int iterations, int kLen, int hashType, int id) 00167 { 00168 /* all in bytes instead of bits */ 00169 word32 u, v, dLen, pLen, iLen, sLen, totalLen; 00170 int dynamic = 0; 00171 int ret = 0; 00172 int i; 00173 byte *D, *S, *P, *I; 00174 byte staticBuffer[1024]; 00175 byte* buffer = staticBuffer; 00176 #ifdef CYASSL_SHA512 00177 byte Ai[SHA512_DIGEST_SIZE]; 00178 byte B[SHA512_BLOCK_SIZE]; 00179 #elif !defined(NO_SHA256) 00180 byte Ai[SHA256_DIGEST_SIZE]; 00181 byte B[SHA256_BLOCK_SIZE]; 00182 #else 00183 byte Ai[SHA_DIGEST_SIZE]; 00184 byte B[SHA_BLOCK_SIZE]; 00185 #endif 00186 00187 if (!iterations) 00188 iterations = 1; 00189 00190 if (hashType == MD5) { 00191 v = MD5_BLOCK_SIZE; 00192 u = MD5_DIGEST_SIZE; 00193 } 00194 else if (hashType == SHA) { 00195 v = SHA_BLOCK_SIZE; 00196 u = SHA_DIGEST_SIZE; 00197 } 00198 #ifndef NO_SHA256 00199 else if (hashType == SHA256) { 00200 v = SHA256_BLOCK_SIZE; 00201 u = SHA256_DIGEST_SIZE; 00202 } 00203 #endif 00204 #ifdef CYASSL_SHA512 00205 else if (hashType == SHA512) { 00206 v = SHA512_BLOCK_SIZE; 00207 u = SHA512_DIGEST_SIZE; 00208 } 00209 #endif 00210 else 00211 return BAD_FUNC_ARG; 00212 00213 dLen = v; 00214 sLen = v * ((saltLen + v - 1) / v); 00215 if (passLen) 00216 pLen = v * ((passLen + v - 1) / v); 00217 else 00218 pLen = 0; 00219 iLen = sLen + pLen; 00220 00221 totalLen = dLen + sLen + pLen; 00222 00223 if (totalLen > sizeof(staticBuffer)) { 00224 buffer = (byte*)XMALLOC(totalLen, 0, DYNAMIC_TYPE_KEY); 00225 if (buffer == NULL) return MEMORY_E; 00226 dynamic = 1; 00227 } 00228 00229 D = buffer; 00230 S = D + dLen; 00231 P = S + sLen; 00232 I = S; 00233 00234 XMEMSET(D, id, dLen); 00235 00236 for (i = 0; i < (int)sLen; i++) 00237 S[i] = salt[i % saltLen]; 00238 for (i = 0; i < (int)pLen; i++) 00239 P[i] = passwd[i % passLen]; 00240 00241 while (kLen > 0) { 00242 word32 currentLen; 00243 mp_int B1; 00244 00245 if (hashType == MD5) { 00246 Md5 md5; 00247 00248 InitMd5(&md5); 00249 Md5Update(&md5, buffer, totalLen); 00250 Md5Final(&md5, Ai); 00251 00252 for (i = 1; i < iterations; i++) { 00253 Md5Update(&md5, Ai, u); 00254 Md5Final(&md5, Ai); 00255 } 00256 } 00257 else if (hashType == SHA) { 00258 Sha sha; 00259 00260 InitSha(&sha); 00261 ShaUpdate(&sha, buffer, totalLen); 00262 ShaFinal(&sha, Ai); 00263 00264 for (i = 1; i < iterations; i++) { 00265 ShaUpdate(&sha, Ai, u); 00266 ShaFinal(&sha, Ai); 00267 } 00268 } 00269 #ifndef NO_SHA256 00270 else if (hashType == SHA256) { 00271 Sha256 sha256; 00272 00273 InitSha256(&sha256); 00274 Sha256Update(&sha256, buffer, totalLen); 00275 Sha256Final(&sha256, Ai); 00276 00277 for (i = 1; i < iterations; i++) { 00278 Sha256Update(&sha256, Ai, u); 00279 Sha256Final(&sha256, Ai); 00280 } 00281 } 00282 #endif 00283 #ifdef CYASSL_SHA512 00284 else if (hashType == SHA512) { 00285 Sha512 sha512; 00286 00287 InitSha512(&sha512); 00288 Sha512Update(&sha512, buffer, totalLen); 00289 Sha512Final(&sha512, Ai); 00290 00291 for (i = 1; i < iterations; i++) { 00292 Sha512Update(&sha512, Ai, u); 00293 Sha512Final(&sha512, Ai); 00294 } 00295 } 00296 #endif 00297 00298 for (i = 0; i < (int)v; i++) 00299 B[i] = Ai[i % u]; 00300 00301 if (mp_init(&B1) != MP_OKAY) 00302 ret = MP_INIT_E; 00303 else if (mp_read_unsigned_bin(&B1, B, v) != MP_OKAY) 00304 ret = MP_READ_E; 00305 else if (mp_add_d(&B1, (mp_digit)1, &B1) != MP_OKAY) 00306 ret = MP_ADD_E; 00307 00308 if (ret != 0) { 00309 mp_clear(&B1); 00310 break; 00311 } 00312 00313 for (i = 0; i < (int)iLen; i += v) { 00314 int outSz; 00315 mp_int i1; 00316 mp_int res; 00317 00318 if (mp_init_multi(&i1, &res, NULL, NULL, NULL, NULL) != MP_OKAY) { 00319 ret = MP_INIT_E; 00320 break; 00321 } 00322 if (mp_read_unsigned_bin(&i1, I + i, v) != MP_OKAY) 00323 ret = MP_READ_E; 00324 else if (mp_add(&i1, &B1, &res) != MP_OKAY) 00325 ret = MP_ADD_E; 00326 else if ( (outSz = mp_unsigned_bin_size(&res)) < 0) 00327 ret = MP_TO_E; 00328 else { 00329 if (outSz > (int)v) { 00330 /* take off MSB */ 00331 byte tmp[129]; 00332 mp_to_unsigned_bin(&res, tmp); 00333 XMEMCPY(I + i, tmp + 1, v); 00334 } 00335 else if (outSz < (int)v) { 00336 XMEMSET(I + i, 0, v - outSz); 00337 mp_to_unsigned_bin(&res, I + i + v - outSz); 00338 } 00339 else 00340 mp_to_unsigned_bin(&res, I + i); 00341 } 00342 00343 mp_clear(&i1); 00344 mp_clear(&res); 00345 if (ret < 0) break; 00346 } 00347 00348 currentLen = min(kLen, (int)u); 00349 XMEMCPY(output, Ai, currentLen); 00350 output += currentLen; 00351 kLen -= currentLen; 00352 mp_clear(&B1); 00353 } 00354 00355 if (dynamic) XFREE(buffer, 0, DYNAMIC_TYPE_KEY); 00356 return ret; 00357 } 00358 00359 #endif /* NO_PWDBASED */ 00360
Generated on Tue Jul 12 2022 20:44:51 by 1.7.2