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.
wc_encrypt.c
00001 /* wc_encrypt.c 00002 * 00003 * Copyright (C) 2006-2017 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL 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 * wolfSSL 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-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfcrypt/settings.h> 00028 #include <wolfcrypt/aes.h> 00029 #include <wolfcrypt/des3.h> 00030 #include <wolfcrypt/hash.h> 00031 #include <wolfcrypt/arc4.h> 00032 #include <wolfcrypt/wc_encrypt.h> 00033 #include <wolfcrypt/error-crypt.h> 00034 #include <wolfcrypt/asn.h> 00035 #include <wolfcrypt/coding.h> 00036 #include <wolfcrypt/pwdbased.h> 00037 #include <wolfcrypt/logging.h> 00038 00039 #ifdef NO_INLINE 00040 #include <wolfcrypt/misc.h> 00041 #else 00042 #define WOLFSSL_MISC_INCLUDED 00043 #include <wolfcrypt/src/misc.c> 00044 #endif 00045 00046 #if !defined(NO_AES) && defined(HAVE_AES_CBC) 00047 #ifdef HAVE_AES_DECRYPT 00048 int wc_AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz, 00049 const byte* key, word32 keySz, const byte* iv) 00050 { 00051 int ret = 0; 00052 #ifdef WOLFSSL_SMALL_STACK 00053 Aes* aes = NULL; 00054 #else 00055 Aes aes[1]; 00056 #endif 00057 00058 if (out == NULL || in == NULL || key == NULL || iv == NULL) { 00059 return BAD_FUNC_ARG; 00060 } 00061 00062 #ifdef WOLFSSL_SMALL_STACK 00063 aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00064 if (aes == NULL) 00065 return MEMORY_E; 00066 #endif 00067 00068 ret = wc_AesInit(aes, NULL, INVALID_DEVID); 00069 if (ret == 0) { 00070 ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION); 00071 if (ret == 0) 00072 ret = wc_AesCbcDecrypt(aes, out, in, inSz); 00073 00074 wc_AesFree(aes); 00075 } 00076 00077 #ifdef WOLFSSL_SMALL_STACK 00078 XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00079 #endif 00080 00081 return ret; 00082 } 00083 #endif /* HAVE_AES_DECRYPT */ 00084 00085 int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz, 00086 const byte* key, word32 keySz, const byte* iv) 00087 { 00088 int ret = 0; 00089 #ifdef WOLFSSL_SMALL_STACK 00090 Aes* aes = NULL; 00091 #else 00092 Aes aes[1]; 00093 #endif 00094 00095 #ifdef WOLFSSL_SMALL_STACK 00096 aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00097 if (aes == NULL) 00098 return MEMORY_E; 00099 #endif 00100 00101 ret = wc_AesInit(aes, NULL, INVALID_DEVID); 00102 if (ret == 0) { 00103 ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION); 00104 if (ret == 0) 00105 ret = wc_AesCbcEncrypt(aes, out, in, inSz); 00106 00107 wc_AesFree(aes); 00108 } 00109 00110 #ifdef WOLFSSL_SMALL_STACK 00111 XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00112 #endif 00113 00114 return ret; 00115 } 00116 #endif /* !NO_AES && HAVE_AES_CBC */ 00117 00118 00119 #ifndef NO_DES3 00120 int wc_Des_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, 00121 const byte* key, const byte* iv) 00122 { 00123 int ret = 0; 00124 #ifdef WOLFSSL_SMALL_STACK 00125 Des* des = NULL; 00126 #else 00127 Des des[1]; 00128 #endif 00129 00130 #ifdef WOLFSSL_SMALL_STACK 00131 des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00132 if (des == NULL) 00133 return MEMORY_E; 00134 #endif 00135 00136 ret = wc_Des_SetKey(des, key, iv, DES_ENCRYPTION); 00137 if (ret == 0) 00138 ret = wc_Des_CbcEncrypt(des, out, in, sz); 00139 00140 #ifdef WOLFSSL_SMALL_STACK 00141 XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00142 #endif 00143 00144 return ret; 00145 } 00146 00147 int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, 00148 const byte* key, const byte* iv) 00149 { 00150 int ret = 0; 00151 #ifdef WOLFSSL_SMALL_STACK 00152 Des* des = NULL; 00153 #else 00154 Des des[1]; 00155 #endif 00156 00157 #ifdef WOLFSSL_SMALL_STACK 00158 des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00159 if (des == NULL) 00160 return MEMORY_E; 00161 #endif 00162 00163 ret = wc_Des_SetKey(des, key, iv, DES_DECRYPTION); 00164 if (ret == 0) 00165 ret = wc_Des_CbcDecrypt(des, out, in, sz); 00166 00167 #ifdef WOLFSSL_SMALL_STACK 00168 XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00169 #endif 00170 00171 return ret; 00172 } 00173 00174 00175 int wc_Des3_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, 00176 const byte* key, const byte* iv) 00177 { 00178 int ret = 0; 00179 #ifdef WOLFSSL_SMALL_STACK 00180 Des3* des3 = NULL; 00181 #else 00182 Des3 des3[1]; 00183 #endif 00184 00185 #ifdef WOLFSSL_SMALL_STACK 00186 des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00187 if (des3 == NULL) 00188 return MEMORY_E; 00189 #endif 00190 00191 ret = wc_Des3Init(des3, NULL, INVALID_DEVID); 00192 if (ret == 0) { 00193 ret = wc_Des3_SetKey(des3, key, iv, DES_ENCRYPTION); 00194 if (ret == 0) 00195 ret = wc_Des3_CbcEncrypt(des3, out, in, sz); 00196 wc_Des3Free(des3); 00197 } 00198 00199 #ifdef WOLFSSL_SMALL_STACK 00200 XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00201 #endif 00202 00203 return ret; 00204 } 00205 00206 00207 int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, 00208 const byte* key, const byte* iv) 00209 { 00210 int ret = 0; 00211 #ifdef WOLFSSL_SMALL_STACK 00212 Des3* des3 = NULL; 00213 #else 00214 Des3 des3[1]; 00215 #endif 00216 00217 #ifdef WOLFSSL_SMALL_STACK 00218 des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00219 if (des3 == NULL) 00220 return MEMORY_E; 00221 #endif 00222 00223 ret = wc_Des3Init(des3, NULL, INVALID_DEVID); 00224 if (ret == 0) { 00225 ret = wc_Des3_SetKey(des3, key, iv, DES_DECRYPTION); 00226 if (ret == 0) 00227 ret = wc_Des3_CbcDecrypt(des3, out, in, sz); 00228 wc_Des3Free(des3); 00229 } 00230 00231 #ifdef WOLFSSL_SMALL_STACK 00232 XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00233 #endif 00234 00235 return ret; 00236 } 00237 00238 #endif /* !NO_DES3 */ 00239 00240 00241 #ifdef WOLFSSL_ENCRYPTED_KEYS 00242 00243 int wc_BufferKeyDecrypt(EncryptedInfo* info, byte* der, word32 derSz, 00244 const byte* password, int passwordSz, int hashType) 00245 { 00246 int ret = NOT_COMPILED_IN; 00247 #ifdef WOLFSSL_SMALL_STACK 00248 byte* key = NULL; 00249 #else 00250 byte key[WC_MAX_SYM_KEY_SIZE]; 00251 #endif 00252 00253 (void)derSz; 00254 (void)passwordSz; 00255 (void)hashType; 00256 00257 if (der == NULL || password == NULL || info == NULL || info->keySz == 0) { 00258 return BAD_FUNC_ARG; 00259 } 00260 00261 /* use file's salt for key derivation, hex decode first */ 00262 if (Base16_Decode(info->iv, info->ivSz, info->iv, &info->ivSz) != 0) { 00263 return BUFFER_E; 00264 } 00265 if (info->ivSz < PKCS5_SALT_SZ) 00266 return BUFFER_E; 00267 00268 #ifdef WOLFSSL_SMALL_STACK 00269 key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); 00270 if (key == NULL) { 00271 return MEMORY_E; 00272 } 00273 #endif 00274 00275 #ifndef NO_PWDBASED 00276 if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1, 00277 info->keySz, hashType)) != 0) { 00278 #ifdef WOLFSSL_SMALL_STACK 00279 XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); 00280 #endif 00281 return ret; 00282 } 00283 #endif 00284 00285 #ifndef NO_DES3 00286 if (info->cipherType == WC_CIPHER_DES) 00287 ret = wc_Des_CbcDecryptWithKey(der, der, derSz, key, info->iv); 00288 if (info->cipherType == WC_CIPHER_DES3) 00289 ret = wc_Des3_CbcDecryptWithKey(der, der, derSz, key, info->iv); 00290 #endif /* NO_DES3 */ 00291 #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(HAVE_AES_DECRYPT) 00292 if (info->cipherType == WC_CIPHER_AES_CBC) 00293 ret = wc_AesCbcDecryptWithKey(der, der, derSz, key, info->keySz, 00294 info->iv); 00295 #endif /* !NO_AES && HAVE_AES_CBC && HAVE_AES_DECRYPT */ 00296 00297 #ifdef WOLFSSL_SMALL_STACK 00298 XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); 00299 #endif 00300 00301 return ret; 00302 } 00303 00304 int wc_BufferKeyEncrypt(EncryptedInfo* info, byte* der, word32 derSz, 00305 const byte* password, int passwordSz, int hashType) 00306 { 00307 int ret = NOT_COMPILED_IN; 00308 #ifdef WOLFSSL_SMALL_STACK 00309 byte* key = NULL; 00310 #else 00311 byte key[WC_MAX_SYM_KEY_SIZE]; 00312 #endif 00313 00314 (void)derSz; 00315 (void)passwordSz; 00316 (void)hashType; 00317 00318 if (der == NULL || password == NULL || info == NULL || info->keySz == 0 || 00319 info->ivSz < PKCS5_SALT_SZ) { 00320 return BAD_FUNC_ARG; 00321 } 00322 00323 #ifdef WOLFSSL_SMALL_STACK 00324 key = (byte*)XMALLOC(WC_MAX_SYM_KEY_SIZE, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); 00325 if (key == NULL) { 00326 return MEMORY_E; 00327 } 00328 #endif /* WOLFSSL_SMALL_STACK */ 00329 00330 #ifndef NO_PWDBASED 00331 if ((ret = wc_PBKDF1(key, password, passwordSz, info->iv, PKCS5_SALT_SZ, 1, 00332 info->keySz, hashType)) != 0) { 00333 #ifdef WOLFSSL_SMALL_STACK 00334 XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); 00335 #endif 00336 return ret; 00337 } 00338 #endif 00339 00340 #ifndef NO_DES3 00341 if (info->cipherType == WC_CIPHER_DES) 00342 ret = wc_Des_CbcEncryptWithKey(der, der, derSz, key, info->iv); 00343 if (info->cipherType == WC_CIPHER_DES3) 00344 ret = wc_Des3_CbcEncryptWithKey(der, der, derSz, key, info->iv); 00345 #endif /* NO_DES3 */ 00346 #ifndef NO_AES 00347 if (info->cipherType == WC_CIPHER_AES_CBC) 00348 ret = wc_AesCbcEncryptWithKey(der, der, derSz, key, info->keySz, 00349 info->iv); 00350 #endif /* NO_AES */ 00351 00352 #ifdef WOLFSSL_SMALL_STACK 00353 XFREE(key, NULL, DYNAMIC_TYPE_SYMETRIC_KEY); 00354 #endif 00355 00356 return ret; 00357 } 00358 00359 #endif /* WOLFSSL_ENCRYPTED_KEYS */ 00360 00361 00362 #ifndef NO_PWDBASED 00363 00364 /* Decrypt/Encrypt input in place from parameters based on id 00365 * 00366 * returns a negative value on fail case 00367 */ 00368 int wc_CryptKey(const char* password, int passwordSz, byte* salt, 00369 int saltSz, int iterations, int id, byte* input, 00370 int length, int version, byte* cbcIv, int enc) 00371 { 00372 int typeH; 00373 int derivedLen; 00374 int ret = 0; 00375 #ifdef WOLFSSL_SMALL_STACK 00376 byte* key; 00377 #else 00378 byte key[MAX_KEY_SIZE]; 00379 #endif 00380 00381 (void)input; 00382 (void)length; 00383 (void)enc; 00384 00385 WOLFSSL_ENTER("wc_CryptKey"); 00386 00387 switch (id) { 00388 #ifndef NO_DES3 00389 #ifndef NO_MD5 00390 case PBE_MD5_DES: 00391 typeH = WC_MD5; 00392 derivedLen = 16; /* may need iv for v1.5 */ 00393 break; 00394 #endif 00395 #ifndef NO_SHA 00396 case PBE_SHA1_DES: 00397 typeH = WC_SHA; 00398 derivedLen = 16; /* may need iv for v1.5 */ 00399 break; 00400 00401 case PBE_SHA1_DES3: 00402 typeH = WC_SHA; 00403 derivedLen = 32; /* may need iv for v1.5 */ 00404 break; 00405 #endif /* !NO_SHA */ 00406 #endif /* !NO_DES3 */ 00407 #if !defined(NO_SHA) && !defined(NO_RC4) 00408 case PBE_SHA1_RC4_128: 00409 typeH = WC_SHA; 00410 derivedLen = 16; 00411 break; 00412 #endif 00413 #ifdef WOLFSSL_AES_256 00414 case PBE_AES256_CBC: 00415 typeH = WC_SHA256; 00416 derivedLen = 32; 00417 break; 00418 #endif 00419 default: 00420 WOLFSSL_MSG("Unknown/Unsupported encrypt/decrypt id"); 00421 return ALGO_ID_E; 00422 } 00423 00424 #ifdef WOLFSSL_SMALL_STACK 00425 key = (byte*)XMALLOC(MAX_KEY_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00426 if (key == NULL) 00427 return MEMORY_E; 00428 #endif 00429 00430 if (version == PKCS5v2) 00431 ret = wc_PBKDF2(key, (byte*)password, passwordSz, 00432 salt, saltSz, iterations, derivedLen, typeH); 00433 #ifndef NO_SHA 00434 else if (version == PKCS5) 00435 ret = wc_PBKDF1(key, (byte*)password, passwordSz, 00436 salt, saltSz, iterations, derivedLen, typeH); 00437 #endif 00438 else if (version == PKCS12v1) { 00439 int i, idx = 0; 00440 byte unicodePasswd[MAX_UNICODE_SZ]; 00441 00442 if ( (passwordSz * 2 + 2) > (int)sizeof(unicodePasswd)) { 00443 #ifdef WOLFSSL_SMALL_STACK 00444 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00445 #endif 00446 return UNICODE_SIZE_E; 00447 } 00448 00449 for (i = 0; i < passwordSz; i++) { 00450 unicodePasswd[idx++] = 0x00; 00451 unicodePasswd[idx++] = (byte)password[i]; 00452 } 00453 /* add trailing NULL */ 00454 unicodePasswd[idx++] = 0x00; 00455 unicodePasswd[idx++] = 0x00; 00456 00457 ret = wc_PKCS12_PBKDF(key, unicodePasswd, idx, salt, saltSz, 00458 iterations, derivedLen, typeH, 1); 00459 if (id != PBE_SHA1_RC4_128) 00460 ret += wc_PKCS12_PBKDF(cbcIv, unicodePasswd, idx, salt, saltSz, 00461 iterations, 8, typeH, 2); 00462 } 00463 else { 00464 #ifdef WOLFSSL_SMALL_STACK 00465 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00466 #endif 00467 WOLFSSL_MSG("Unknown/Unsupported PKCS version"); 00468 return ALGO_ID_E; 00469 } 00470 00471 if (ret != 0) { 00472 #ifdef WOLFSSL_SMALL_STACK 00473 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00474 #endif 00475 return ret; 00476 } 00477 00478 switch (id) { 00479 #ifndef NO_DES3 00480 #if !defined(NO_SHA) || !defined(NO_MD5) 00481 case PBE_MD5_DES: 00482 case PBE_SHA1_DES: 00483 { 00484 Des des; 00485 byte* desIv = key + 8; 00486 00487 if (version == PKCS5v2 || version == PKCS12v1) 00488 desIv = cbcIv; 00489 00490 if (enc) { 00491 ret = wc_Des_SetKey(&des, key, desIv, DES_ENCRYPTION); 00492 } 00493 else { 00494 ret = wc_Des_SetKey(&des, key, desIv, DES_DECRYPTION); 00495 } 00496 if (ret != 0) { 00497 #ifdef WOLFSSL_SMALL_STACK 00498 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00499 #endif 00500 return ret; 00501 } 00502 00503 if (enc) { 00504 wc_Des_CbcEncrypt(&des, input, input, length); 00505 } 00506 else { 00507 wc_Des_CbcDecrypt(&des, input, input, length); 00508 } 00509 break; 00510 } 00511 #endif /* !NO_SHA || !NO_MD5 */ 00512 00513 #ifndef NO_SHA 00514 case PBE_SHA1_DES3: 00515 { 00516 Des3 des; 00517 byte* desIv = key + 24; 00518 00519 if (version == PKCS5v2 || version == PKCS12v1) 00520 desIv = cbcIv; 00521 00522 ret = wc_Des3Init(&des, NULL, INVALID_DEVID); 00523 if (ret != 0) { 00524 #ifdef WOLFSSL_SMALL_STACK 00525 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00526 #endif 00527 return ret; 00528 } 00529 if (enc) { 00530 ret = wc_Des3_SetKey(&des, key, desIv, DES_ENCRYPTION); 00531 } 00532 else { 00533 ret = wc_Des3_SetKey(&des, key, desIv, DES_DECRYPTION); 00534 } 00535 if (ret != 0) { 00536 #ifdef WOLFSSL_SMALL_STACK 00537 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00538 #endif 00539 return ret; 00540 } 00541 if (enc) { 00542 ret = wc_Des3_CbcEncrypt(&des, input, input, length); 00543 } 00544 else { 00545 ret = wc_Des3_CbcDecrypt(&des, input, input, length); 00546 } 00547 if (ret != 0) { 00548 #ifdef WOLFSSL_SMALL_STACK 00549 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00550 #endif 00551 return ret; 00552 } 00553 break; 00554 } 00555 #endif /* !NO_SHA */ 00556 #endif 00557 #if !defined(NO_RC4) && !defined(NO_SHA) 00558 case PBE_SHA1_RC4_128: 00559 { 00560 Arc4 dec; 00561 00562 wc_Arc4SetKey(&dec, key, derivedLen); 00563 wc_Arc4Process(&dec, input, input, length); 00564 break; 00565 } 00566 #endif 00567 #ifndef NO_AES 00568 #ifdef WOLFSSL_AES_256 00569 case PBE_AES256_CBC: 00570 { 00571 Aes dec; 00572 ret = wc_AesInit(&dec, NULL, INVALID_DEVID); 00573 if (ret == 0) 00574 ret = wc_AesSetKey(&dec, key, derivedLen, 00575 cbcIv, AES_DECRYPTION); 00576 if (ret == 0) 00577 ret = wc_AesCbcDecrypt(&dec, input, input, length); 00578 if (ret != 0) { 00579 #ifdef WOLFSSL_SMALL_STACK 00580 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00581 #endif 00582 return ret; 00583 } 00584 ForceZero(&dec, sizeof(Aes)); 00585 break; 00586 } 00587 #endif /* WOLFSSL_AES_256 */ 00588 #endif 00589 00590 default: 00591 #ifdef WOLFSSL_SMALL_STACK 00592 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00593 #endif 00594 WOLFSSL_MSG("Unknown/Unsupported encrypt/decryption algorithm"); 00595 return ALGO_ID_E; 00596 } 00597 00598 #ifdef WOLFSSL_SMALL_STACK 00599 XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00600 #endif 00601 00602 return ret; 00603 } 00604 00605 #endif /* !NO_PWDBASED */ 00606
Generated on Tue Jul 12 2022 16:58:12 by
1.7.2