Skip to content

Commit 977811c

Browse files
authored
Merge pull request #169 from LinuxJedi/f-fixes2
More static analysis fixes
2 parents 3543f30 + 9bb9c33 commit 977811c

7 files changed

Lines changed: 1086 additions & 17 deletions

File tree

src/crypto.c

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3209,6 +3209,8 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
32093209
if (!WP11_Session_IsOpInitialized(session, WP11_INIT_AES_GCM_DEC))
32103210
return CKR_OPERATION_NOT_INITIALIZED;
32113211

3212+
if (ulEncryptedDataLen < (CK_ULONG)WP11_AesGcm_GetTagBits(session) / 8)
3213+
return CKR_ENCRYPTED_DATA_LEN_RANGE;
32123214
decDataLen = (word32)ulEncryptedDataLen -
32133215
WP11_AesGcm_GetTagBits(session) / 8;
32143216
if (pData == NULL) {
@@ -3230,6 +3232,8 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
32303232
if (!WP11_Session_IsOpInitialized(session, WP11_INIT_AES_CCM_DEC))
32313233
return CKR_OPERATION_NOT_INITIALIZED;
32323234

3235+
if (ulEncryptedDataLen < (CK_ULONG)WP11_AesCcm_GetMacLen(session))
3236+
return CKR_ENCRYPTED_DATA_LEN_RANGE;
32333237
decDataLen = (word32)ulEncryptedDataLen -
32343238
WP11_AesCcm_GetMacLen(session);
32353239
if (pData == NULL) {
@@ -3294,9 +3298,10 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
32943298
if (!WP11_Session_IsOpInitialized(session, WP11_INIT_AES_KEYWRAP_DEC))
32953299
return CKR_OPERATION_NOT_INITIALIZED;
32963300

3297-
/* AES Key Wrap unwrapping reduces the size by 8 bytes (the
3298-
* integrity check value). If using padding then its even smaller
3299-
* but we can't know the final size without decrypting first. */
3301+
/* AES Key Wrap ciphertext is at least two semiblocks: one data
3302+
* semiblock plus the 8-byte integrity check value. */
3303+
if (ulEncryptedDataLen < 2 * KEYWRAP_BLOCK_SIZE)
3304+
return CKR_ENCRYPTED_DATA_LEN_RANGE;
33003305
decDataLen = (word32)(ulEncryptedDataLen - KEYWRAP_BLOCK_SIZE);
33013306
if (pData == NULL) {
33023307
*pulDataLen = decDataLen;
@@ -3312,12 +3317,31 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
33123317
if (mechanism == CKM_AES_KEY_WRAP_PAD) {
33133318
int i;
33143319
byte padValue = pData[decDataLen - 1];
3315-
if (padValue > KEYWRAP_BLOCK_SIZE || padValue > decDataLen)
3316-
return CKR_ENCRYPTED_DATA_LEN_RANGE;
3317-
for (i = 0; i < padValue; i++) {
3318-
if (pData[decDataLen - 1 - i] != padValue)
3319-
return CKR_ENCRYPTED_DATA_INVALID;
3320+
unsigned int badPad = 0;
3321+
unsigned int inPad;
3322+
3323+
/* Constant-time range check: padValue must be 1..KEYWRAP_BLOCK_SIZE
3324+
* and must not exceed decDataLen. */
3325+
badPad |= ((unsigned int)padValue - 1) >> 31;
3326+
badPad |= ((unsigned int)KEYWRAP_BLOCK_SIZE -
3327+
(unsigned int)padValue) >> 31;
3328+
badPad |= ((unsigned int)decDataLen -
3329+
(unsigned int)padValue) >> 31;
3330+
3331+
/* Constant-time padding byte verification.
3332+
* Always iterate KEYWRAP_BLOCK_SIZE times to avoid leaking
3333+
* padValue through iteration count. */
3334+
for (i = 0; i < KEYWRAP_BLOCK_SIZE; i++) {
3335+
/* Full mask: all-ones when i < padValue, else 0 */
3336+
inPad = 0 - (((unsigned int)i -
3337+
(unsigned int)padValue) >> 31);
3338+
badPad |= inPad &
3339+
((unsigned int)pData[decDataLen - 1 - i] ^
3340+
(unsigned int)padValue);
33203341
}
3342+
3343+
if (badPad != 0)
3344+
return CKR_ENCRYPTED_DATA_INVALID;
33213345
decDataLen -= padValue;
33223346
}
33233347
*pulDataLen = decDataLen;
@@ -3623,6 +3647,9 @@ CK_RV C_DecryptFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart,
36233647
if (!WP11_Session_IsOpInitialized(session, WP11_INIT_AES_GCM_DEC))
36243648
return CKR_OPERATION_NOT_INITIALIZED;
36253649

3650+
if (WP11_AesGcm_EncDataLen(session) <
3651+
WP11_AesGcm_GetTagBits(session) / 8)
3652+
return CKR_ENCRYPTED_DATA_LEN_RANGE;
36263653
decPartLen = WP11_AesGcm_EncDataLen(session) -
36273654
WP11_AesGcm_GetTagBits(session) / 8;
36283655
if (pLastPart == NULL) {

src/internal.c

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,17 @@
102102
#error "wolfTPM and MAXQ10XX are incompatible with each other."
103103
#endif
104104

105+
/* wc_ForceZero was added in wolfSSL 5.8.4. Provide a fallback for older
106+
* versions to securely zero sensitive memory. */
107+
#if defined(LIBWOLFSSL_VERSION_HEX) && LIBWOLFSSL_VERSION_HEX >= 0x05008004
108+
#include <wolfssl/wolfcrypt/memory.h>
109+
#else
110+
static void wc_ForceZero(void* mem, size_t len) {
111+
volatile byte* p = (volatile byte*)mem;
112+
while (len--) *p++ = 0;
113+
}
114+
#endif
115+
105116
/* Helper to get size of struct field */
106117
#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
107118

@@ -2738,7 +2749,10 @@ int WP11_Object_Copy(WP11_Object *src, WP11_Object *dest)
27382749
}
27392750
}
27402751

2741-
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2752+
if (derBuf != NULL) {
2753+
wc_ForceZero(derBuf, derSz);
2754+
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2755+
}
27422756

27432757
/* Free destination key on failure */
27442758
if (ret != 0) {
@@ -2811,7 +2825,7 @@ int WP11_Object_Copy(WP11_Object *src, WP11_Object *dest)
28112825

28122826
/* Clean up */
28132827
if (derBuf != NULL) {
2814-
XMEMSET(derBuf, 0, derSz); /* Clear sensitive data */
2828+
wc_ForceZero(derBuf, derSz);
28152829
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28162830
}
28172831

@@ -7819,8 +7833,8 @@ int WP11_Session_SetCcmParams(WP11_Session* session, int dataSz,
78197833
ret = BAD_FUNC_ARG;
78207834

78217835
if (ret == 0) {
7822-
ccm->dataSz = dataSz;
78237836
XMEMSET(ccm, 0, sizeof(*ccm));
7837+
ccm->dataSz = dataSz;
78247838
XMEMCPY(ccm->iv, iv, ivSz);
78257839
ccm->ivSz = ivSz;
78267840
if (aad != NULL) {
@@ -8285,8 +8299,7 @@ void WP11_Object_Free(WP11_Object* object)
82858299
#endif
82868300
if ((object->type == CKK_AES || object->type == CKK_GENERIC_SECRET ||
82878301
object->type == CKK_HKDF) && object->data.symmKey != NULL) {
8288-
/* TODO: ForceZero */
8289-
XMEMSET(object->data.symmKey->data, 0, object->data.symmKey->len);
8302+
wc_ForceZero(object->data.symmKey->data, object->data.symmKey->len);
82908303
XFREE(object->data.symmKey, NULL, DYNAMIC_TYPE_AES);
82918304
object->data.symmKey = NULL;
82928305
}
@@ -9931,6 +9944,9 @@ static int GetEcbCheckValue(WP11_Object* secret, byte* dataOut,
99319944
XFREE(hash, NULL, DYNAMIC_TYPE_TMP_BUFFER);
99329945
XFREE(input, NULL, DYNAMIC_TYPE_TMP_BUFFER);
99339946

9947+
if (ret != 0)
9948+
return CKR_FUNCTION_FAILED;
9949+
99349950
return CKR_OK;
99359951
}
99369952
#endif
@@ -12991,7 +13007,26 @@ int WP11_AesCbcPad_DecryptFinal(unsigned char* dec, word32* decSz,
1299113007
ret = wc_AesCbcDecrypt(&cbc->aes, cbc->partial, cbc->partial,
1299213008
cbc->partialSz);
1299313009
if (ret == 0) {
13010+
byte padBad;
13011+
1299413012
padCnt = cbc->partial[AES_BLOCK_SIZE-1];
13013+
13014+
/* Validate PKCS#7 padding in constant time:
13015+
* padCnt must be 1..AES_BLOCK_SIZE and all padding bytes must equal
13016+
* padCnt. */
13017+
padBad = (byte)(0 - (padCnt == 0));
13018+
padBad |= (byte)(0 - (padCnt > AES_BLOCK_SIZE));
13019+
for (i = 0; i < AES_BLOCK_SIZE; i++) {
13020+
/* inPad is 0xFF when i is in the padding region, 0x00 otherwise */
13021+
byte inPad = (byte)(0 -
13022+
((unsigned)(AES_BLOCK_SIZE - 1 - i) < (unsigned)padCnt));
13023+
padBad |= inPad & (cbc->partial[i] ^ padCnt);
13024+
}
13025+
if (padBad) {
13026+
ret = BAD_PADDING_E;
13027+
}
13028+
}
13029+
if (ret == 0) {
1299513030
outSz = AES_BLOCK_SIZE - (padCnt & (0 - (padCnt <= AES_BLOCK_SIZE)));
1299613031
for (i = 0; i < AES_BLOCK_SIZE; i++) {
1299713032
mask = (size_t)0 - (i != outSz);

src/slot.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static CK_MECHANISM_TYPE mechanismList[] = {
328328
#ifdef WC_RSA_PSS
329329
CKM_RSA_PKCS_PSS,
330330
#ifndef NO_SHA
331-
CKM_SHA1_RSA_PKCS,
331+
CKM_SHA1_RSA_PKCS_PSS,
332332
#endif
333333
#ifdef WOLFSSL_SHA224
334334
CKM_SHA224_RSA_PKCS_PSS,
@@ -579,12 +579,10 @@ static CK_MECHANISM_INFO rsaPssMechInfo = {
579579
1024, 4096, CKF_SIGN | CKF_VERIFY
580580
};
581581
#endif
582-
#ifndef NO_SHA256
583582
static CK_MECHANISM_INFO shaRsaPkcsMechInfo = {
584583
1024, 4096, CKF_SIGN | CKF_VERIFY
585584
};
586585
#endif
587-
#endif
588586
#ifdef HAVE_ECC
589587
/* Info on EC key generation mechanism. */
590588
static CK_MECHANISM_INFO ecKgMechInfo = {

src/wolfpkcs11.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ CK_RV C_GetInterfaceList(CK_INTERFACE_PTR pInterfacesList, CK_ULONG_PTR pulCount
448448
return CKR_BUFFER_TOO_SMALL;
449449
}
450450

451-
memcpy(pInterfacesList, interfaces, NUM_INTERFACES * sizeof(CK_INTERFACE));
451+
XMEMCPY(pInterfacesList, interfaces, NUM_INTERFACES * sizeof(CK_INTERFACE));
452452
*pulCount = NUM_INTERFACES;
453453

454454
return CKR_OK;

0 commit comments

Comments
 (0)