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