mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-02 04:04:39 +02:00
pkcs7: refactoring PKCS7_DecodeEnvelopedData to reduce stack usage: ~ 9 * sizeof(mp_int) bytes + 512 bytes moved to the heap.
--- variable privKey moved to the heap (more than 8 * sizeof(mp_int) bytes saved) --- variable encryptedKey moved to the heap (512 bytes saved) --- variable serialNum moved to the heap (sizeof(mp_int) bytes saved)
This commit is contained in:
@@ -1410,14 +1410,23 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
word32 savedIdx = 0, idx = 0;
|
word32 savedIdx = 0, idx = 0;
|
||||||
word32 contentType, encOID;
|
word32 contentType, encOID;
|
||||||
byte issuerHash[SHA_DIGEST_SIZE];
|
byte issuerHash[SHA_DIGEST_SIZE];
|
||||||
mp_int serialNum;
|
|
||||||
|
|
||||||
int encryptedKeySz, keySz;
|
int encryptedKeySz, keySz;
|
||||||
byte tmpIv[DES_BLOCK_SIZE];
|
byte tmpIv[DES_BLOCK_SIZE];
|
||||||
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
|
||||||
byte* decryptedKey = NULL;
|
byte* decryptedKey = NULL;
|
||||||
|
|
||||||
RsaKey privKey;
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
mp_int* serialNum;
|
||||||
|
byte* encryptedKey;
|
||||||
|
RsaKey* privKey;
|
||||||
|
#else
|
||||||
|
mp_int stack_serialNum;
|
||||||
|
mp_int* serialNum = &stack_serialNum;
|
||||||
|
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||||
|
|
||||||
|
RsaKey stack_privKey;
|
||||||
|
RsaKey* privKey = &stack_privKey;
|
||||||
|
#endif
|
||||||
int encryptedContentSz;
|
int encryptedContentSz;
|
||||||
byte padLen;
|
byte padLen;
|
||||||
byte* encryptedContent = NULL;
|
byte* encryptedContent = NULL;
|
||||||
@@ -1431,18 +1440,6 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
output == NULL || outputSz == 0)
|
output == NULL || outputSz == 0)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* load private key */
|
|
||||||
ret = InitRsaKey(&privKey, 0);
|
|
||||||
if (ret != 0) return ret;
|
|
||||||
ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, &privKey,
|
|
||||||
pkcs7->privateKeySz);
|
|
||||||
if (ret != 0) {
|
|
||||||
CYASSL_MSG("Failed to decode RSA private key");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = 0;
|
|
||||||
|
|
||||||
/* read past ContentInfo, verify type is envelopedData */
|
/* read past ContentInfo, verify type is envelopedData */
|
||||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
@@ -1477,6 +1474,13 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
encryptedKey = (byte*) XMALLOC(MAX_ENCRYPTED_KEY_SZ, NULL,
|
||||||
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (encryptedKey == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
#endif
|
||||||
|
|
||||||
savedIdx = idx;
|
savedIdx = idx;
|
||||||
recipFound = 0;
|
recipFound = 0;
|
||||||
|
|
||||||
@@ -1496,38 +1500,85 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version != 0)
|
if (version != 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_VERSION_E;
|
return ASN_VERSION_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* remove IssuerAndSerialNumber */
|
/* remove IssuerAndSerialNumber */
|
||||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0)
|
if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* if we found correct recipient, issuer hashes will match */
|
/* if we found correct recipient, issuer hashes will match */
|
||||||
if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) {
|
if (XMEMCMP(issuerHash, pkcs7->issuerHash, SHA_DIGEST_SIZE) == 0) {
|
||||||
recipFound = 1;
|
recipFound = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetInt(&serialNum, pkiMsg, &idx, pkiMsgSz) < 0)
|
#ifdef CYASSL_SMALL_STACK
|
||||||
return ASN_PARSE_E;
|
serialNum = (mp_int*)XMALLOC(sizeof(mp_int), NULL,
|
||||||
mp_clear(&serialNum);
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (serialNum == NULL) {
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0)
|
if (GetInt(serialNum, pkiMsg, &idx, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
|
mp_clear(serialNum);
|
||||||
|
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(serialNum, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* key encryption algorithm must be RSA for now */
|
/* key encryption algorithm must be RSA for now */
|
||||||
if (encOID != RSAk)
|
if (encOID != RSAk) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ALGO_ID_E;
|
return ALGO_ID_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* read encryptedKey */
|
/* read encryptedKey */
|
||||||
if (pkiMsg[idx++] != ASN_OCTET_STRING)
|
if (pkiMsg[idx++] != ASN_OCTET_STRING) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (recipFound == 1)
|
if (recipFound == 1)
|
||||||
XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz);
|
XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz);
|
||||||
@@ -1539,28 +1590,54 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
|
|
||||||
if (recipFound == 0) {
|
if (recipFound == 0) {
|
||||||
CYASSL_MSG("No recipient found in envelopedData that matches input");
|
CYASSL_MSG("No recipient found in envelopedData that matches input");
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return PKCS7_RECIP_E;
|
return PKCS7_RECIP_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove EncryptedContentInfo */
|
/* remove EncryptedContentInfo */
|
||||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
|
if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0)
|
if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
/* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
|
/* get block cipher IV, stored in OPTIONAL parameter of AlgoID */
|
||||||
if (pkiMsg[idx++] != ASN_OCTET_STRING)
|
if (pkiMsg[idx++] != ASN_OCTET_STRING) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (length != DES_BLOCK_SIZE) {
|
if (length != DES_BLOCK_SIZE) {
|
||||||
CYASSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE");
|
CYASSL_MSG("Incorrect IV length, must be of DES_BLOCK_SIZE");
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1568,25 +1645,78 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
idx += length;
|
idx += length;
|
||||||
|
|
||||||
/* read encryptedContent, cont[0] */
|
/* read encryptedContent, cont[0] */
|
||||||
if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0))
|
if (pkiMsg[idx++] != (ASN_CONTEXT_SPECIFIC | 0)) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0)
|
if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
}
|
||||||
|
|
||||||
encryptedContent = XMALLOC(encryptedContentSz, NULL,
|
encryptedContent = (byte*)XMALLOC(encryptedContentSz, NULL,
|
||||||
DYNAMIC_TYPE_TMP_BUFFER);
|
DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
if (encryptedContent == NULL)
|
if (encryptedContent == NULL) {
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
|
}
|
||||||
|
|
||||||
XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
|
XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
|
||||||
|
|
||||||
|
/* load private key */
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
privKey = (RsaKey*)XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
if (privKey == NULL) {
|
||||||
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = InitRsaKey(privKey, 0);
|
||||||
|
if (ret != 0) {
|
||||||
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
|
ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, privKey,
|
||||||
|
pkcs7->privateKeySz);
|
||||||
|
if (ret != 0) {
|
||||||
|
CYASSL_MSG("Failed to decode RSA private key");
|
||||||
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* decrypt encryptedKey */
|
/* decrypt encryptedKey */
|
||||||
keySz = RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
|
keySz = RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
|
||||||
&decryptedKey, &privKey);
|
&decryptedKey, privKey);
|
||||||
FreeRsaKey(&privKey);
|
FreeRsaKey(privKey);
|
||||||
|
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (keySz <= 0) {
|
if (keySz <= 0) {
|
||||||
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return keySz;
|
return keySz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1601,6 +1731,9 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1613,11 +1746,17 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
|
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CYASSL_MSG("Unsupported content encryption OID type");
|
CYASSL_MSG("Unsupported content encryption OID type");
|
||||||
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
return ALGO_ID_E;
|
return ALGO_ID_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1630,6 +1769,9 @@ CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
|||||||
XMEMSET(encryptedKey, 0, MAX_ENCRYPTED_KEY_SZ);
|
XMEMSET(encryptedKey, 0, MAX_ENCRYPTED_KEY_SZ);
|
||||||
XMEMSET(encryptedContent, 0, encryptedContentSz);
|
XMEMSET(encryptedContent, 0, encryptedContentSz);
|
||||||
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#ifdef CYASSL_SMALL_STACK
|
||||||
|
XFREE(encryptedKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
#endif
|
||||||
|
|
||||||
return encryptedContentSz - padLen;
|
return encryptedContentSz - padLen;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user