ssl: refactoring ProcessBuffer to reduce stack usage:

--- variable password moved to the heap (80 bytes saved)
--- variable key moved to the heap (32 bytes saved)
--- variable iv moved to the heap (16 bytes saved)
--- variable Des moved to the heap (sizeof(Des) saved)
--- variable Des3 moved to the heap (sizeof(Des3) saved)
--- variable Aes moved to the heap (sizeof(Aes) saved)
--- variable RsaKey moved to the heap (sizeof(RsaKey) saved)

Utility functions added to Des, Des3 and Aes for easier decryption.
This commit is contained in:
Moisés Guimarães 2014-09-15 20:57:52 -03:00
parent df3ea53494
commit d9472d65da
5 changed files with 165 additions and 50 deletions

View File

@ -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 */ /* AES-DIRECT */
#if defined(CYASSL_AES_DIRECT) #if defined(CYASSL_AES_DIRECT)
#if defined(FREESCALE_MMCAU) #if defined(FREESCALE_MMCAU)

View File

@ -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) int Des3_SetIV(Des3* des, const byte* iv)
{ {
if (des && 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 #ifdef HAVE_CAVIUM
#include "cavium_common.h" #include "cavium_common.h"

View File

@ -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 AesSetIV(Aes* aes, const byte* iv);
CYASSL_API int AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); 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 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 AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz);
CYASSL_API void AesEncryptDirect(Aes* aes, byte* out, const byte* in); CYASSL_API void AesEncryptDirect(Aes* aes, byte* out, const byte* in);
CYASSL_API void AesDecryptDirect(Aes* aes, byte* out, const byte* in); CYASSL_API void AesDecryptDirect(Aes* aes, byte* out, const byte* in);

View File

@ -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_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_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_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_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_SetIV(Des3* des, const byte* iv);
CYASSL_API int Des3_CbcEncrypt(Des3* des, byte* out, const byte* in,word32 sz); 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_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 #ifdef HAVE_CAVIUM

125
src/ssl.c
View File

@ -2183,14 +2183,34 @@ static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
if (info->set) { if (info->set) {
/* decrypt */ /* decrypt */
char password[80]; int passwordSz;
int passwordSz; #ifdef CYASSL_SMALL_STACK
char* password = NULL;
byte key[AES_256_KEY_SIZE]; byte* key = NULL;
byte* iv = NULL;
#else
char password[80];
byte key[AES_256_KEY_SIZE];
byte iv[AES_IV_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) { if (!ctx || !ctx->passwd_cb) {
return NO_PASSWORD; ret = NO_PASSWORD;
} }
else { else {
passwordSz = ctx->passwd_cb(password, sizeof(password), 0, passwordSz = ctx->passwd_cb(password, sizeof(password), 0,
@ -2206,50 +2226,36 @@ static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
/* empty */ /* empty */
} }
else if (XSTRNCMP(info->name, "DES-CBC", 7) == 0) { else if (XSTRNCMP(info->name, "DES-CBC", 7) == 0) {
Des enc; ret = Des_CbcDecryptWithKey(der.buffer, der.buffer, der.length,
key, info->iv);
ret = Des_SetKey(&enc, key, info->iv, DES_DECRYPTION);
if (ret == 0)
Des_CbcDecrypt(&enc, der.buffer, der.buffer,
der.length);
} }
else if (XSTRNCMP(info->name, "DES-EDE3-CBC", 13) == 0) { else if (XSTRNCMP(info->name, "DES-EDE3-CBC", 13) == 0) {
Des3 enc; ret = Des3_CbcDecryptWithKey(der.buffer, der.buffer, der.length,
key, info->iv);
ret = Des3_SetKey(&enc, key, info->iv, DES_DECRYPTION);
if (ret == 0)
ret = Des3_CbcDecrypt(&enc, der.buffer, der.buffer,
der.length);
} }
else if (XSTRNCMP(info->name, "AES-128-CBC", 13) == 0) { else if (XSTRNCMP(info->name, "AES-128-CBC", 13) == 0) {
Aes enc; ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
ret = AesSetKey(&enc, key, AES_128_KEY_SIZE, info->iv, key, AES_128_KEY_SIZE, info->iv);
AES_DECRYPTION);
if (ret == 0)
ret = AesCbcDecrypt(&enc, der.buffer, der.buffer,
der.length);
} }
else if (XSTRNCMP(info->name, "AES-192-CBC", 13) == 0) { else if (XSTRNCMP(info->name, "AES-192-CBC", 13) == 0) {
Aes enc; ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
ret = AesSetKey(&enc, key, AES_192_KEY_SIZE, info->iv, key, AES_192_KEY_SIZE, info->iv);
AES_DECRYPTION);
if (ret == 0)
ret = AesCbcDecrypt(&enc, der.buffer, der.buffer,
der.length);
} }
else if (XSTRNCMP(info->name, "AES-256-CBC", 13) == 0) { else if (XSTRNCMP(info->name, "AES-256-CBC", 13) == 0) {
Aes enc; ret = AesCbcDecryptWithKey(der.buffer, der.buffer, der.length,
ret = AesSetKey(&enc, key, AES_256_KEY_SIZE, info->iv, key, AES_256_KEY_SIZE, info->iv);
AES_DECRYPTION);
if (ret == 0)
ret = AesCbcDecrypt(&enc, der.buffer, der.buffer,
der.length);
} }
else { else {
ret = SSL_BAD_FILE; 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) { if (ret != 0) {
#ifdef CYASSL_SMALL_STACK #ifdef CYASSL_SMALL_STACK
XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(info, NULL, DYNAMIC_TYPE_TMP_BUFFER);
@ -2308,25 +2314,44 @@ static int ProcessBuffer(CYASSL_CTX* ctx, const unsigned char* buff,
#ifndef NO_RSA #ifndef NO_RSA
if (!eccKey) { if (!eccKey) {
/* make sure RSA key can be used */ /* make sure RSA key can be used */
RsaKey key;
word32 idx = 0; word32 idx = 0;
#ifdef CYASSL_SMALL_STACK
RsaKey* key = NULL;
#else
RsaKey key[1];
#endif
ret = InitRsaKey(&key, 0); #ifdef CYASSL_SMALL_STACK
if (ret != 0) return ret; key = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL,
if (RsaPrivateKeyDecode(der.buffer,&idx,&key,der.length) != 0) { DYNAMIC_TYPE_TMP_BUFFER);
#ifdef HAVE_ECC if (key == NULL)
/* could have DER ECC (or pkcs8 ecc), no easy way to tell */ return MEMORY_E;
eccKey = 1; /* so try it out */ #endif
#endif
if (!eccKey) { ret = InitRsaKey(key, 0);
FreeRsaKey(&key); if (ret == 0) {
return SSL_BAD_FILE; 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 #endif
#ifdef HAVE_ECC #ifdef HAVE_ECC