@@ -1416,6 +1416,173 @@ int test_aes_gcm_bad_tag(void *data)
14161416 return err ;
14171417}
14181418
1419+ static int test_aes_gcm_tls_iv_fixed_oversized_helper (OSSL_LIB_CTX * libCtx ,
1420+ const char * cipherName , int keyLen )
1421+ {
1422+ int err ;
1423+ EVP_CIPHER * cipher = NULL ;
1424+ EVP_CIPHER_CTX * ctx = NULL ;
1425+ unsigned char key [32 ];
1426+ /* ivLen (12, the GCM default) + EVP_GCM_TLS_EXPLICIT_IV_LEN (8) = 20: */
1427+ unsigned char iv [20 ];
1428+
1429+ memset (key , 0xCC , keyLen );
1430+ memset (iv , 0xDD , sizeof (iv ));
1431+
1432+ cipher = EVP_CIPHER_fetch (libCtx , cipherName , "" );
1433+ err = cipher == NULL ;
1434+
1435+ if (err == 0 ) {
1436+ ctx = EVP_CIPHER_CTX_new ();
1437+ err = ctx == NULL ;
1438+ }
1439+ if (err == 0 ) {
1440+ err = EVP_DecryptInit_ex (ctx , cipher , NULL , key , NULL ) != 1 ;
1441+ }
1442+ if (err == 0 ) {
1443+ err = EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IV_FIXED ,
1444+ EVP_GCM_TLS_FIXED_IV_LEN , iv ) != 1 ;
1445+ }
1446+ EVP_CIPHER_CTX_free (ctx );
1447+ ctx = NULL ;
1448+
1449+ if (err == 0 ) {
1450+ ctx = EVP_CIPHER_CTX_new ();
1451+ err = ctx == NULL ;
1452+ }
1453+ if (err == 0 ) {
1454+ err = EVP_DecryptInit_ex (ctx , cipher , NULL , key , NULL ) != 1 ;
1455+ }
1456+ if (err == 0 ) {
1457+ int ivLen = EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN ;
1458+ if (EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IV_FIXED ,
1459+ ivLen , iv ) == 1 ) {
1460+ PRINT_ERR_MSG ("%s: EVP_CTRL_GCM_SET_IV_FIXED incorrectly "
1461+ "accepted a fixed IV length (%d) equal to the "
1462+ "IV length, leaving no room for the explicit "
1463+ "field" , cipherName , ivLen );
1464+ err = 1 ;
1465+ }
1466+ }
1467+ EVP_CIPHER_CTX_free (ctx );
1468+ ctx = NULL ;
1469+
1470+ /* Oversized fixed len (> ctx->ivLen, default 12) must be rejected. */
1471+ if (err == 0 ) {
1472+ ctx = EVP_CIPHER_CTX_new ();
1473+ err = ctx == NULL ;
1474+ }
1475+ if (err == 0 ) {
1476+ err = EVP_DecryptInit_ex (ctx , cipher , NULL , key , NULL ) != 1 ;
1477+ }
1478+ if (err == 0 ) {
1479+ if (EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_GCM_SET_IV_FIXED ,
1480+ (int )sizeof (iv ), iv ) == 1 ) {
1481+ PRINT_ERR_MSG ("%s: EVP_CTRL_GCM_SET_IV_FIXED incorrectly "
1482+ "accepted a fixed IV length (%d) larger than "
1483+ "the IV length" , cipherName , (int )sizeof (iv ));
1484+ err = 1 ;
1485+ }
1486+ }
1487+
1488+ EVP_CIPHER_CTX_free (ctx );
1489+ EVP_CIPHER_free (cipher );
1490+ return err ;
1491+ }
1492+
1493+ int test_aes_gcm_tls_iv_fixed_oversized (void * data )
1494+ {
1495+ int err ;
1496+
1497+ (void )data ;
1498+
1499+ PRINT_MSG ("AES-128-GCM TLS1 fixed-IV length boundary rejection" );
1500+ err = test_aes_gcm_tls_iv_fixed_oversized_helper (wpLibCtx ,
1501+ "AES-128-GCM" , 16 );
1502+ if (err == 0 ) {
1503+ PRINT_MSG ("AES-256-GCM TLS1 fixed-IV length boundary rejection" );
1504+ err = test_aes_gcm_tls_iv_fixed_oversized_helper (wpLibCtx ,
1505+ "AES-256-GCM" , 32 );
1506+ }
1507+
1508+ return err ;
1509+ }
1510+
1511+ /*
1512+ * Test that GCM tag lengths are validated against the NIST SP 800-38D table.
1513+ */
1514+ static int test_aes_gcm_tag_len_helper (OSSL_LIB_CTX * libCtx ,
1515+ const char * cipherName )
1516+ {
1517+ int err ;
1518+ int i ;
1519+ EVP_CIPHER * cipher = NULL ;
1520+ EVP_CIPHER_CTX * ctx = NULL ;
1521+ unsigned char tag [16 ];
1522+ static const int invalidLen [] = { 1 , 2 , 3 , 5 , 6 , 7 };
1523+ static const int validLen [] = { 4 , 8 , 12 , 13 , 14 , 15 , 16 };
1524+ int numInvalid = (int )(sizeof (invalidLen ) / sizeof (invalidLen [0 ]));
1525+ int numValid = (int )(sizeof (validLen ) / sizeof (validLen [0 ]));
1526+
1527+ memset (tag , 0 , sizeof (tag ));
1528+
1529+ cipher = EVP_CIPHER_fetch (libCtx , cipherName , "" );
1530+ err = cipher == NULL ;
1531+
1532+ for (i = 0 ; (err == 0 ) && (i < numInvalid ); i ++ ) {
1533+ ctx = EVP_CIPHER_CTX_new ();
1534+ err = ctx == NULL ;
1535+ if (err == 0 ) {
1536+ err = EVP_DecryptInit (ctx , cipher , NULL , NULL ) != 1 ;
1537+ }
1538+ if ((err == 0 ) &&
1539+ EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_AEAD_SET_TAG , invalidLen [i ],
1540+ tag ) == 1 ) {
1541+ PRINT_ERR_MSG ("%s: EVP_CTRL_AEAD_SET_TAG incorrectly accepted "
1542+ "tag length %d" , cipherName , invalidLen [i ]);
1543+ err = 1 ;
1544+ }
1545+ EVP_CIPHER_CTX_free (ctx );
1546+ ctx = NULL ;
1547+ }
1548+
1549+ for (i = 0 ; (err == 0 ) && (i < numValid ); i ++ ) {
1550+ ctx = EVP_CIPHER_CTX_new ();
1551+ err = ctx == NULL ;
1552+ if (err == 0 ) {
1553+ err = EVP_DecryptInit (ctx , cipher , NULL , NULL ) != 1 ;
1554+ }
1555+ if ((err == 0 ) &&
1556+ EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_AEAD_SET_TAG , validLen [i ],
1557+ tag ) != 1 ) {
1558+ PRINT_ERR_MSG ("%s: EVP_CTRL_AEAD_SET_TAG incorrectly rejected "
1559+ "tag length %d" , cipherName , validLen [i ]);
1560+ err = 1 ;
1561+ }
1562+ EVP_CIPHER_CTX_free (ctx );
1563+ ctx = NULL ;
1564+ }
1565+
1566+ EVP_CIPHER_free (cipher );
1567+ return err ;
1568+ }
1569+
1570+ int test_aes_gcm_tag_len_undersized (void * data )
1571+ {
1572+ int err ;
1573+
1574+ (void )data ;
1575+
1576+ PRINT_MSG ("AES-128-GCM tag length validation" );
1577+ err = test_aes_gcm_tag_len_helper (wpLibCtx , "AES-128-GCM" );
1578+ if (err == 0 ) {
1579+ PRINT_MSG ("AES-256-GCM tag length validation" );
1580+ err = test_aes_gcm_tag_len_helper (wpLibCtx , "AES-256-GCM" );
1581+ }
1582+
1583+ return err ;
1584+ }
1585+
14191586#endif /* WP_HAVE_AESGCM */
14201587
14211588/******************************************************************************/
@@ -1601,5 +1768,89 @@ int test_aes_ccm_bad_tag(void *data)
16011768 return err ;
16021769}
16031770
1771+ /*
1772+ * Test that CCM tag lengths are validated against the NIST SP 800-38C.
1773+ */
1774+ static int test_aes_ccm_tag_len_helper (OSSL_LIB_CTX * libCtx ,
1775+ const char * cipherName )
1776+ {
1777+ int err ;
1778+ int i ;
1779+ EVP_CIPHER * cipher = NULL ;
1780+ EVP_CIPHER_CTX * ctx = NULL ;
1781+ unsigned char iv [13 ];
1782+ unsigned char tag [16 ];
1783+ static const int invalidLen [] = { 1 , 2 , 3 , 5 , 7 , 9 };
1784+ static const int validLen [] = { 4 , 6 , 8 , 10 , 12 , 14 , 16 };
1785+ int numInvalid = (int )(sizeof (invalidLen ) / sizeof (invalidLen [0 ]));
1786+ int numValid = (int )(sizeof (validLen ) / sizeof (validLen [0 ]));
1787+
1788+ memset (tag , 0 , sizeof (tag ));
1789+
1790+ cipher = EVP_CIPHER_fetch (libCtx , cipherName , "" );
1791+ err = cipher == NULL ;
1792+
1793+ for (i = 0 ; (err == 0 ) && (i < numInvalid ); i ++ ) {
1794+ ctx = EVP_CIPHER_CTX_new ();
1795+ err = ctx == NULL ;
1796+ if (err == 0 ) {
1797+ err = EVP_DecryptInit (ctx , cipher , NULL , NULL ) != 1 ;
1798+ }
1799+ if (err == 0 ) {
1800+ err = EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_AEAD_SET_IVLEN ,
1801+ (int )sizeof (iv ), NULL ) != 1 ;
1802+ }
1803+ if ((err == 0 ) &&
1804+ EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_AEAD_SET_TAG , invalidLen [i ],
1805+ tag ) == 1 ) {
1806+ PRINT_ERR_MSG ("%s: EVP_CTRL_AEAD_SET_TAG incorrectly accepted "
1807+ "tag length %d" , cipherName , invalidLen [i ]);
1808+ err = 1 ;
1809+ }
1810+ EVP_CIPHER_CTX_free (ctx );
1811+ ctx = NULL ;
1812+ }
1813+
1814+ for (i = 0 ; (err == 0 ) && (i < numValid ); i ++ ) {
1815+ ctx = EVP_CIPHER_CTX_new ();
1816+ err = ctx == NULL ;
1817+ if (err == 0 ) {
1818+ err = EVP_DecryptInit (ctx , cipher , NULL , NULL ) != 1 ;
1819+ }
1820+ if (err == 0 ) {
1821+ err = EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_AEAD_SET_IVLEN ,
1822+ (int )sizeof (iv ), NULL ) != 1 ;
1823+ }
1824+ if ((err == 0 ) &&
1825+ EVP_CIPHER_CTX_ctrl (ctx , EVP_CTRL_AEAD_SET_TAG , validLen [i ],
1826+ tag ) != 1 ) {
1827+ PRINT_ERR_MSG ("%s: EVP_CTRL_AEAD_SET_TAG incorrectly rejected "
1828+ "tag length %d" , cipherName , validLen [i ]);
1829+ err = 1 ;
1830+ }
1831+ EVP_CIPHER_CTX_free (ctx );
1832+ ctx = NULL ;
1833+ }
1834+
1835+ EVP_CIPHER_free (cipher );
1836+ return err ;
1837+ }
1838+
1839+ int test_aes_ccm_tag_len_undersized (void * data )
1840+ {
1841+ int err ;
1842+
1843+ (void )data ;
1844+
1845+ PRINT_MSG ("AES-128-CCM tag length validation" );
1846+ err = test_aes_ccm_tag_len_helper (wpLibCtx , "AES-128-CCM" );
1847+ if (err == 0 ) {
1848+ PRINT_MSG ("AES-256-CCM tag length validation" );
1849+ err = test_aes_ccm_tag_len_helper (wpLibCtx , "AES-256-CCM" );
1850+ }
1851+
1852+ return err ;
1853+ }
1854+
16041855#endif /* WP_HAVE_AESCCM */
16051856
0 commit comments