Skip to content

Commit ff5292c

Browse files
committed
Fix error in CT compare, add negative tests for TLS pad checks
1 parent 19b69b5 commit ff5292c

5 files changed

Lines changed: 393 additions & 1 deletion

File tree

src/wp_internal.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ byte wp_ct_byte_mask_eq(byte a, byte b)
11721172
*/
11731173
byte wp_ct_byte_mask_ne(byte a, byte b)
11741174
{
1175-
return (((int32_t)b - a) >> 31) & (((int32_t)a - b) >> 31);
1175+
return (((int32_t)b - a) >> 31) | (((int32_t)a - b) >> 31);
11761176
}
11771177

11781178
/**

test/test_cipher.c

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,86 @@ int test_des3_cbc_stream(void *data)
457457
return err;
458458
}
459459

460+
/*
461+
* Negative PKCS#7 padding test for DES3-CBC.
462+
* Encrypt block-aligned plaintext (produces a full padding block), corrupt a
463+
* ciphertext byte so the padding block is garbled, verify DecryptFinal rejects.
464+
*/
465+
int test_des3_cbc_bad_pad(void *data)
466+
{
467+
int err = 0;
468+
EVP_CIPHER *cipher = NULL;
469+
EVP_CIPHER_CTX *ctx = NULL;
470+
unsigned char key[24];
471+
unsigned char iv[8];
472+
unsigned char pt[8]; /* block-aligned: PKCS#7 adds full 8-byte pad block */
473+
unsigned char ct[24]; /* 8 pt + 8 pad = 16, but EncryptFinal may need room */
474+
unsigned char dec[24];
475+
int outLen = 0, fLen = 0;
476+
477+
(void)data;
478+
479+
PRINT_MSG("DES3-CBC negative PKCS#7 padding");
480+
481+
memset(key, 0xAA, sizeof(key));
482+
memset(iv, 0xBB, sizeof(iv));
483+
memset(pt, 0x42, sizeof(pt));
484+
485+
cipher = EVP_CIPHER_fetch(wpLibCtx, "DES-EDE3-CBC", "");
486+
if (cipher == NULL) {
487+
err = 1;
488+
}
489+
490+
/* Encrypt with padding. */
491+
if (err == 0) {
492+
ctx = EVP_CIPHER_CTX_new();
493+
if (ctx == NULL)
494+
err = 1;
495+
}
496+
if (err == 0) {
497+
err = EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv) != 1;
498+
}
499+
if (err == 0) {
500+
err = EVP_EncryptUpdate(ctx, ct, &outLen, pt, (int)sizeof(pt)) != 1;
501+
}
502+
if (err == 0) {
503+
err = EVP_EncryptFinal_ex(ctx, ct + outLen, &fLen) != 1;
504+
outLen += fLen;
505+
}
506+
EVP_CIPHER_CTX_free(ctx);
507+
ctx = NULL;
508+
509+
/* Corrupt first ciphertext block -- CBC garbles the padding block. */
510+
if (err == 0) {
511+
ct[0] ^= 0x01;
512+
}
513+
514+
/* Decrypt -- DecryptFinal should fail due to garbled padding. */
515+
if (err == 0) {
516+
ctx = EVP_CIPHER_CTX_new();
517+
if (ctx == NULL)
518+
err = 1;
519+
}
520+
if (err == 0) {
521+
err = EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv) != 1;
522+
}
523+
if (err == 0) {
524+
fLen = 0;
525+
err = EVP_DecryptUpdate(ctx, dec, &fLen, ct, outLen) != 1;
526+
}
527+
if (err == 0) {
528+
int ret = EVP_DecryptFinal_ex(ctx, dec + fLen, &fLen);
529+
if (ret == 1) {
530+
PRINT_ERR_MSG("DES3-CBC bad-pad: DecryptFinal should have failed");
531+
err = 1;
532+
}
533+
}
534+
535+
EVP_CIPHER_CTX_free(ctx);
536+
EVP_CIPHER_free(cipher);
537+
return err;
538+
}
539+
460540
#endif /* WP_HAVE_DES3CBC */
461541

462542
/******************************************************************************/
@@ -1326,4 +1406,86 @@ int test_aes256_cbc_multiple(void *data)
13261406

13271407
return err;
13281408
}
1409+
1410+
/*
1411+
* Negative PKCS#7 padding test for AES-256-CBC.
1412+
* Encrypt block-aligned plaintext (produces a full padding block), corrupt a
1413+
* ciphertext byte so the padding block is garbled, verify DecryptFinal rejects.
1414+
*/
1415+
int test_aes256_cbc_bad_pad(void *data)
1416+
{
1417+
int err = 0;
1418+
EVP_CIPHER *cipher = NULL;
1419+
EVP_CIPHER_CTX *ctx = NULL;
1420+
unsigned char key[32];
1421+
unsigned char iv[16];
1422+
unsigned char pt[16]; /* block-aligned: PKCS#7 adds full 16-byte pad block */
1423+
unsigned char ct[48];
1424+
unsigned char dec[48];
1425+
int outLen = 0, fLen = 0;
1426+
1427+
(void)data;
1428+
1429+
PRINT_MSG("AES-256-CBC negative PKCS#7 padding");
1430+
1431+
memset(key, 0xAA, sizeof(key));
1432+
memset(iv, 0xBB, sizeof(iv));
1433+
memset(pt, 0x42, sizeof(pt));
1434+
1435+
cipher = EVP_CIPHER_fetch(wpLibCtx, "AES-256-CBC", "");
1436+
if (cipher == NULL) {
1437+
err = 1;
1438+
}
1439+
1440+
/* Encrypt with padding. */
1441+
if (err == 0) {
1442+
ctx = EVP_CIPHER_CTX_new();
1443+
if (ctx == NULL)
1444+
err = 1;
1445+
}
1446+
if (err == 0) {
1447+
err = EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv) != 1;
1448+
}
1449+
if (err == 0) {
1450+
err = EVP_EncryptUpdate(ctx, ct, &outLen, pt, (int)sizeof(pt)) != 1;
1451+
}
1452+
if (err == 0) {
1453+
err = EVP_EncryptFinal_ex(ctx, ct + outLen, &fLen) != 1;
1454+
outLen += fLen;
1455+
}
1456+
EVP_CIPHER_CTX_free(ctx);
1457+
ctx = NULL;
1458+
1459+
/* Corrupt first ciphertext block -- CBC garbles the padding block. */
1460+
if (err == 0) {
1461+
ct[0] ^= 0x01;
1462+
}
1463+
1464+
/* Decrypt -- DecryptFinal should fail due to garbled padding. */
1465+
if (err == 0) {
1466+
ctx = EVP_CIPHER_CTX_new();
1467+
if (ctx == NULL)
1468+
err = 1;
1469+
}
1470+
if (err == 0) {
1471+
err = EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv) != 1;
1472+
}
1473+
if (err == 0) {
1474+
fLen = 0;
1475+
err = EVP_DecryptUpdate(ctx, dec, &fLen, ct, outLen) != 1;
1476+
}
1477+
if (err == 0) {
1478+
int ret = EVP_DecryptFinal_ex(ctx, dec + fLen, &fLen);
1479+
if (ret == 1) {
1480+
PRINT_ERR_MSG("AES-256-CBC bad-pad: DecryptFinal should have "
1481+
"failed");
1482+
err = 1;
1483+
}
1484+
}
1485+
1486+
EVP_CIPHER_CTX_free(ctx);
1487+
EVP_CIPHER_free(cipher);
1488+
return err;
1489+
}
1490+
13291491
#endif /* WP_HAVE_AESCBC */

0 commit comments

Comments
 (0)