@@ -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