diff --git a/ctaocrypt/src/aes.c b/ctaocrypt/src/aes.c index 53c62eb89..ff2e9d5c2 100644 --- a/ctaocrypt/src/aes.c +++ b/ctaocrypt/src/aes.c @@ -1575,6 +1575,34 @@ int AesSetIV(Aes* aes, const byte* iv) } +int AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz, + const byte* key, word32 keySz, const byte* iv) +{ + int ret = 0; +#ifdef CYASSL_SMALL_STACK + Aes* aes = NULL; +#else + Aes aes[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + aes = (Aes*)XMALLOC(sizeof(Aes), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (aes == NULL) + return MEMORY_E; +#endif + + ret = AesSetKey(aes, key, keySz, iv, AES_DECRYPTION); + if (ret == 0) + ret = AesCbcDecrypt(aes, out, in, inSz); + +#ifdef CYASSL_SMALL_STACK + XFREE(aes, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + + /* AES-DIRECT */ #if defined(CYASSL_AES_DIRECT) #if defined(FREESCALE_MMCAU) diff --git a/ctaocrypt/src/des3.c b/ctaocrypt/src/des3.c index 670b6022b..59198c1f1 100644 --- a/ctaocrypt/src/des3.c +++ b/ctaocrypt/src/des3.c @@ -1389,6 +1389,34 @@ void Des_SetIV(Des* des, const byte* iv) } +int Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, + const byte* key, const byte* iv) +{ + int ret = 0; +#ifdef CYASSL_SMALL_STACK + Des* des = NULL; +#else + Des des[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + des = (Des*)XMALLOC(sizeof(Des), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (des == NULL) + return MEMORY_E; +#endif + + ret = Des_SetKey(des, key, iv, DES_DECRYPTION); + if (ret == 0) + ret = Des_CbcDecrypt(des, out, in, sz); + +#ifdef CYASSL_SMALL_STACK + XFREE(des, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + + int Des3_SetIV(Des3* des, const byte* iv) { if (des && iv) @@ -1400,6 +1428,34 @@ int Des3_SetIV(Des3* des, const byte* iv) } +int Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, + const byte* key, const byte* iv) +{ + int ret = 0; +#ifdef CYASSL_SMALL_STACK + Des3* des3 = NULL; +#else + Des3 des3[1]; +#endif + +#ifdef CYASSL_SMALL_STACK + des3 = (Des3*)XMALLOC(sizeof(Des3), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (des3 == NULL) + return MEMORY_E; +#endif + + ret = Des3_SetKey(des3, key, iv, DES_DECRYPTION); + if (ret == 0) + ret = Des3_CbcDecrypt(des3, out, in, sz); + +#ifdef CYASSL_SMALL_STACK + XFREE(des3, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + + #ifdef HAVE_CAVIUM #include "cavium_common.h" diff --git a/cyassl/ctaocrypt/aes.h b/cyassl/ctaocrypt/aes.h index 69d86abf3..c381f77bd 100644 --- a/cyassl/ctaocrypt/aes.h +++ b/cyassl/ctaocrypt/aes.h @@ -110,6 +110,8 @@ CYASSL_API int AesSetKey(Aes* aes, const byte* key, word32 len, const byte* iv, CYASSL_API int AesSetIV(Aes* aes, const byte* iv); CYASSL_API int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); CYASSL_API int AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz); +CYASSL_API int AesCbcDecryptWithKey(byte* out, const byte* in, word32 inSz, + const byte* key, word32 keySz, const byte* iv); CYASSL_API void AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); CYASSL_API void AesEncryptDirect(Aes* aes, byte* out, const byte* in); CYASSL_API void AesDecryptDirect(Aes* aes, byte* out, const byte* in); diff --git a/cyassl/ctaocrypt/des3.h b/cyassl/ctaocrypt/des3.h index 0c8f64006..fb386ee45 100644 --- a/cyassl/ctaocrypt/des3.h +++ b/cyassl/ctaocrypt/des3.h @@ -85,11 +85,15 @@ CYASSL_API void Des_SetIV(Des* des, const byte* iv); CYASSL_API int Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz); CYASSL_API int Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz); CYASSL_API int Des_EcbEncrypt(Des* des, byte* out, const byte* in, word32 sz); +CYASSL_API int Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, + const byte* key, const byte* iv); CYASSL_API int Des3_SetKey(Des3* des, const byte* key, const byte* iv,int dir); CYASSL_API int Des3_SetIV(Des3* des, const byte* iv); CYASSL_API int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in,word32 sz); CYASSL_API int Des3_CbcDecrypt(Des3* des, byte* out, const byte* in,word32 sz); +CYASSL_API int Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, + const byte* key, const byte* iv); #ifdef HAVE_CAVIUM diff --git a/src/ssl.c b/src/ssl.c index ae6ae79a4..82bf7f9fe 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2183,14 +2183,34 @@ static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff, #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) if (info->set) { /* decrypt */ - char password[80]; - int passwordSz; - - byte key[AES_256_KEY_SIZE]; + int passwordSz; +#ifdef CYASSL_SMALL_STACK + char* password = NULL; + byte* key = NULL; + byte* iv = NULL; +#else + char password[80]; + byte key[AES_256_KEY_SIZE]; byte iv[AES_IV_SIZE]; +#endif + #ifdef CYASSL_SMALL_STACK + password = (char*)XMALLOC(80, NULL, DYNAMIC_TYPE_TMP_BUFFER); + key = (byte*)XMALLOC(AES_256_KEY_SIZE, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + iv = (byte*)XMALLOC(AES_IV_SIZE, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + + if (password == NULL || key == NULL || iv == NULL) { + XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(iv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + ret = MEMORY_E; + } + else + #endif if (!ctx || !ctx->passwd_cb) { - return NO_PASSWORD; + ret = NO_PASSWORD; } else { passwordSz = ctx->passwd_cb(password, sizeof(password), 0, @@ -2206,50 +2226,36 @@ static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff, /* empty */ } else if (XSTRNCMP(info->name, "DES-CBC", 7) == 0) { - Des enc; - - ret = Des_SetKey(&enc, key, info->iv, DES_DECRYPTION); - if (ret == 0) - Des_CbcDecrypt(&enc, der.buffer, der.buffer, - der.length); + ret = Des_CbcDecryptWithKey(der.buffer, der.buffer, der.length, + key, info->iv); } else if (XSTRNCMP(info->name, "DES-EDE3-CBC", 13) == 0) { - Des3 enc; - - ret = Des3_SetKey(&enc, key, info->iv, DES_DECRYPTION); - if (ret == 0) - ret = Des3_CbcDecrypt(&enc, der.buffer, der.buffer, - der.length); + ret = Des3_CbcDecryptWithKey(der.buffer, der.buffer, der.length, + key, info->iv); } else if (XSTRNCMP(info->name, "AES-128-CBC", 13) == 0) { - Aes enc; - ret = AesSetKey(&enc, key, AES_128_KEY_SIZE, info->iv, - AES_DECRYPTION); - if (ret == 0) - ret = AesCbcDecrypt(&enc, der.buffer, der.buffer, - der.length); + ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length, + key, AES_128_KEY_SIZE, info->iv); } else if (XSTRNCMP(info->name, "AES-192-CBC", 13) == 0) { - Aes enc; - ret = AesSetKey(&enc, key, AES_192_KEY_SIZE, info->iv, - AES_DECRYPTION); - if (ret == 0) - ret = AesCbcDecrypt(&enc, der.buffer, der.buffer, - der.length); + ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length, + key, AES_192_KEY_SIZE, info->iv); } else if (XSTRNCMP(info->name, "AES-256-CBC", 13) == 0) { - Aes enc; - ret = AesSetKey(&enc, key, AES_256_KEY_SIZE, info->iv, - AES_DECRYPTION); - if (ret == 0) - ret = AesCbcDecrypt(&enc, der.buffer, der.buffer, - der.length); + ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length, + key, AES_256_KEY_SIZE, info->iv); } else { ret = SSL_BAD_FILE; } } + #ifdef CYASSL_SMALL_STACK + XFREE(password, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(iv, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + if (ret != 0) { #ifdef CYASSL_SMALL_STACK XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -2308,25 +2314,44 @@ static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff, #ifndef NO_RSA if (!eccKey) { /* make sure RSA key can be used */ - RsaKey key; word32 idx = 0; + #ifdef CYASSL_SMALL_STACK + RsaKey* key = NULL; + #else + RsaKey key[1]; + #endif - ret = InitRsaKey(&key, 0); - if (ret != 0) return ret; - if (RsaPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) { - #ifdef HAVE_ECC - /* could have DER ECC (or pkcs8 ecc), no easy way to tell */ - eccKey = 1; /* so try it out */ - #endif - if (!eccKey) { - FreeRsaKey(&key); - return SSL_BAD_FILE; + #ifdef CYASSL_SMALL_STACK + key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (key == NULL) + return MEMORY_E; + #endif + + ret = InitRsaKey(key, 0); + if (ret == 0) { + if (RsaPrivateKeyDecode(der.buffer, &idx, key, der.length) != + 0) { + #ifdef HAVE_ECC + /* could have DER ECC (or pkcs8 ecc), no easy way to tell */ + eccKey = 1; /* so try it out */ + #endif + if (!eccKey) + ret = SSL_BAD_FILE; + } else { + rsaKey = 1; + (void)rsaKey; /* for no ecc builds */ } - } else { - rsaKey = 1; - (void)rsaKey; /* for no ecc builds */ } - FreeRsaKey(&key); + + FreeRsaKey(key); + + #ifdef CYASSL_SMALL_STACK + XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + + if (ret != 0) + return ret; } #endif #ifdef HAVE_ECC