Skip to content

Commit fea8d1b

Browse files
authored
Merge pull request #10413 from JeremiahM37/fenrir-7
zeroize sensitive memory and validate public API inputs
2 parents 9a46ecb + 51072bb commit fea8d1b

17 files changed

Lines changed: 159 additions & 17 deletions

File tree

tests/api.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12119,6 +12119,19 @@ static int test_wc_PemToDer(void)
1211912119
XFREE(cert_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1212012120
}
1212112121
#endif
12122+
/* NULL buff, zero size, and negative size must be rejected up front. The
12123+
* pre-fix code cast longSz to word32, so a negative value drove an
12124+
* over-read inside PemToDer. */
12125+
{
12126+
const byte stub[] = "x";
12127+
DerBuffer* badDer = NULL;
12128+
ExpectIntEQ(wc_PemToDer(NULL, 100, CERT_TYPE, &badDer, NULL, &info,
12129+
&eccKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
12130+
ExpectIntEQ(wc_PemToDer(stub, 0, CERT_TYPE, &badDer, NULL, &info,
12131+
&eccKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
12132+
ExpectIntEQ(wc_PemToDer(stub, -1, CERT_TYPE, &badDer, NULL, &info,
12133+
&eccKey), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
12134+
}
1212212135
#endif
1212312136
return EXPECT_RESULT();
1212412137
}

tests/api/test_camellia.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,38 @@ int test_wc_CamelliaSetIV(void)
107107
return EXPECT_RESULT();
108108
} /* END test_wc_CamelliaSetIV*/
109109

110+
/*
111+
* Test wc_CamelliaFree zeroes the key schedule and is NULL safe.
112+
*/
113+
int test_wc_CamelliaFree(void)
114+
{
115+
EXPECT_DECLS;
116+
#ifdef HAVE_CAMELLIA
117+
wc_Camellia camellia;
118+
static const byte key[] = {
119+
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
120+
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10
121+
};
122+
static const byte iv[] = {
123+
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
124+
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
125+
};
126+
byte zero[sizeof(camellia)];
127+
128+
XMEMSET(zero, 0, sizeof(zero));
129+
130+
/* NULL is safe. */
131+
wc_CamelliaFree(NULL);
132+
133+
/* After SetKey the schedule is populated; Free must wipe it. */
134+
ExpectIntEQ(wc_CamelliaSetKey(&camellia, key, (word32)sizeof(key), iv), 0);
135+
ExpectIntNE(XMEMCMP(&camellia, zero, sizeof(camellia)), 0);
136+
wc_CamelliaFree(&camellia);
137+
ExpectIntEQ(XMEMCMP(&camellia, zero, sizeof(camellia)), 0);
138+
#endif
139+
return EXPECT_RESULT();
140+
} /* END test_wc_CamelliaFree */
141+
110142
/*
111143
* Test wc_CamelliaEncryptDirect and wc_CamelliaDecryptDirect
112144
*/

tests/api/test_camellia.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626

2727
int test_wc_CamelliaSetKey(void);
2828
int test_wc_CamelliaSetIV(void);
29+
int test_wc_CamelliaFree(void);
2930
int test_wc_CamelliaEncryptDecryptDirect(void);
3031
int test_wc_CamelliaCbcEncryptDecrypt(void);
3132
int test_wc_CamelliaCbc_MonteCarlo(void);
3233

3334
#define TEST_CAMELLIA_DECLS \
3435
TEST_DECL_GROUP("camellia", test_wc_CamelliaSetKey), \
3536
TEST_DECL_GROUP("camellia", test_wc_CamelliaSetIV), \
37+
TEST_DECL_GROUP("camellia", test_wc_CamelliaFree), \
3638
TEST_DECL_GROUP("camellia", test_wc_CamelliaEncryptDecryptDirect), \
3739
TEST_DECL_GROUP("camellia", test_wc_CamelliaCbcEncryptDecrypt), \
3840
TEST_DECL_GROUP("camellia", test_wc_CamelliaCbc_MonteCarlo)

tests/api/test_pkcs7.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5028,6 +5028,14 @@ int test_wc_PKCS7_DecodeCompressedData(void)
50285028
ExpectNotNull(decompressed);
50295029
ExpectIntEQ(XMEMCMP(decompressed, cert_buf, cert_sz), 0);
50305030
XFREE(decompressed, heap, DYNAMIC_TYPE_TMP_BUFFER);
5031+
decompressed = NULL;
5032+
5033+
/* inSz that would overflow on the initial 'tmpSz = inSz * 2' must be
5034+
* rejected up front rather than handed to XMALLOC. */
5035+
ExpectIntEQ(wc_DeCompressDynamic(&decompressed, -1, DYNAMIC_TYPE_TMP_BUFFER,
5036+
out, ((word32)INT_MAX / 2) + 1, 0, heap),
5037+
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
5038+
ExpectNull(decompressed);
50315039

50325040
if (cert_buf != NULL)
50335041
XFREE(cert_buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);

wolfcrypt/src/asn.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24806,7 +24806,14 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
2480624806
int wc_PemToDer(const unsigned char* buff, long longSz, int type,
2480724807
DerBuffer** pDer, void* heap, EncryptedInfo* info, int* keyFormat)
2480824808
{
24809-
int ret = PemToDer(buff, longSz, type, pDer, heap, info, keyFormat);
24809+
int ret;
24810+
24811+
if (buff == NULL || longSz <= 0) {
24812+
WOLFSSL_MSG("Bad pem der args");
24813+
return BAD_FUNC_ARG;
24814+
}
24815+
24816+
ret = PemToDer(buff, longSz, type, pDer, heap, info, keyFormat);
2481024817
#if defined(HAVE_PKCS8) || defined(HAVE_PKCS12)
2481124818
if (ret == 0 && type == PRIVATEKEY_TYPE) {
2481224819
DerBuffer* der = *pDer;

wolfcrypt/src/camellia.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,5 +1634,13 @@ int wc_CamelliaCbcDecrypt(wc_Camellia* cam, byte* out, const byte* in, word32 sz
16341634
}
16351635

16361636

1637+
void wc_CamelliaFree(wc_Camellia* cam)
1638+
{
1639+
if (cam == NULL)
1640+
return;
1641+
ForceZero(cam, sizeof(wc_Camellia));
1642+
}
1643+
1644+
16371645
#endif /* HAVE_CAMELLIA */
16381646

wolfcrypt/src/compress.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,11 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
221221
if (out == NULL || in == NULL) {
222222
return BAD_FUNC_ARG;
223223
}
224+
/* Cap input so the initial doubling and additive growth in the loop
225+
* cannot overflow word32 or the int return type. */
226+
if (inSz > (word32)(INT_MAX / 2)) {
227+
return BAD_FUNC_ARG;
228+
}
224229
i = (maxSz == 1)? 1 : 2; /* start with output buffer twice the size of input
225230
* unless max was set to 1 */
226231

@@ -229,7 +234,7 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
229234
/* Check for source > 64K on 16-bit machine: */
230235
if ((uLong)stream.avail_in != inSz) return DECOMPRESS_INIT_E;
231236

232-
tmpSz = inSz * i;
237+
tmpSz = inSz * (word32)i;
233238
tmp = (byte*)XMALLOC(tmpSz, heap, memoryType);
234239
if (tmp == NULL)
235240
return MEMORY_E;
@@ -278,6 +283,11 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
278283
}
279284
i++;
280285

286+
if (tmpSz > (word32)INT_MAX - inSz) {
287+
WOLFSSL_MSG("Decompress buffer would exceed INT_MAX");
288+
result = DECOMPRESS_E;
289+
break;
290+
}
281291
newSz = tmpSz + inSz;
282292
newTmp = (byte*)XMALLOC(newSz, heap, memoryType);
283293
if (newTmp == NULL) {
@@ -295,13 +305,18 @@ int wc_DeCompressDynamic(byte** out, int maxSz, int memoryType,
295305
} while (result == Z_OK);
296306

297307
if (result == Z_STREAM_END) {
298-
result = (int)stream.total_out;
299-
*out = (byte*)XMALLOC(result, heap, memoryType);
300-
if (*out != NULL) {
301-
XMEMCPY(*out, tmp, result);
308+
if (stream.total_out > (uLong)INT_MAX) {
309+
result = DECOMPRESS_E;
302310
}
303311
else {
304-
result = MEMORY_E;
312+
result = (int)stream.total_out;
313+
*out = (byte*)XMALLOC(result, heap, memoryType);
314+
if (*out != NULL) {
315+
XMEMCPY(*out, tmp, result);
316+
}
317+
else {
318+
result = MEMORY_E;
319+
}
305320
}
306321
}
307322
else {

wolfcrypt/src/curve25519.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p,
250250
for (cnt = 0; cnt < WOLFSSL_CURVE25519_BLINDING_RAND_CNT; cnt++) {
251251
ret = wc_RNG_GenerateBlock(rng, rz, sizeof(rz));
252252
if (ret < 0) {
253-
return ret;
253+
goto cleanup;
254254
}
255255
for (i = CURVE25519_KEYSIZE - 1; i >= 0; i--) {
256256
if (rz[i] != 0xff)
@@ -261,13 +261,14 @@ static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p,
261261
}
262262
}
263263
if (cnt == WOLFSSL_CURVE25519_BLINDING_RAND_CNT) {
264-
return RNG_FAILURE_E;
264+
ret = RNG_FAILURE_E;
265+
goto cleanup;
265266
}
266267

267268
/* Generate 253 random bits. */
268269
ret = wc_RNG_GenerateBlock(rng, a, sizeof(a));
269270
if (ret != 0)
270-
return ret;
271+
goto cleanup;
271272
a[CURVE25519_KEYSIZE-1] &= 0x7f;
272273
/* k' = k ^ 2k ^ a */
273274
n_a[0] = n[0] ^ (byte)(n[0] << 1) ^ a[0];
@@ -281,6 +282,11 @@ static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p,
281282
/* Scalar multiple blinded scalar with blinding value. */
282283
ret = curve25519_blind(rp, n_a, a, p, rz);
283284

285+
cleanup:
286+
ForceZero(a, sizeof(a));
287+
ForceZero(n_a, sizeof(n_a));
288+
ForceZero(rz, sizeof(rz));
289+
284290
RESTORE_VECTOR_REGISTERS();
285291

286292
return ret;

wolfcrypt/src/ed25519.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
548548
}
549549
ret = ctMaskGT(c, 0) & SIG_VERIFY_E;
550550
}
551+
ForceZero(orig_k, sizeof(orig_k));
551552
#endif
552553

553554
return ret;

wolfcrypt/src/ed448.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ int wc_ed448_sign_msg_ex(const byte* in, word32 inLen, byte* out,
505505
}
506506
ret = ctMaskGT(c, 0) & SIG_VERIFY_E;
507507
}
508+
ForceZero(orig_k, sizeof(orig_k));
508509
#endif
509510

510511
ForceZero(az, sizeof(az));

0 commit comments

Comments
 (0)