@@ -130,6 +130,8 @@ static const EVP_CIPHER *GetCipher(const std::string &name) {
130130 return EVP_aes_256_ccm ();
131131 } else if (name == " XAES-256-GCM" ) {
132132 return EVP_xaes_256_gcm ();
133+ } else if (name == " XAES-256-GCM-KC" ) {
134+ return EVP_xaes_256_gcm_kc ();
133135 }
134136 return nullptr ;
135137}
@@ -186,14 +188,16 @@ static void TestCipherAPI(const EVP_CIPHER *cipher, Operation op, bool padding,
186188 bssl::Span<const uint8_t > plaintext,
187189 bssl::Span<const uint8_t > ciphertext,
188190 bssl::Span<const uint8_t > aad,
189- bssl::Span<const uint8_t > tag) {
191+ bssl::Span<const uint8_t > tag,
192+ bssl::Span<const uint8_t > kc = {}) {
190193 bool encrypt = op == Operation::kEncrypt ;
191194 bool is_custom_cipher =
192195 EVP_CIPHER_flags (cipher) & EVP_CIPH_FLAG_CUSTOM_CIPHER;
193196 bssl::Span<const uint8_t > in = encrypt ? plaintext : ciphertext;
194197 bssl::Span<const uint8_t > expected = encrypt ? ciphertext : plaintext;
195198 bool is_aead = EVP_CIPHER_flags (cipher) & EVP_CIPH_FLAG_AEAD_CIPHER;
196199 bool is_ccm = EVP_CIPHER_mode (cipher) == EVP_CIPH_CCM_MODE;
200+ bool is_kc = EVP_CIPHER_flags (cipher) & EVP_CIPH_FLAG_KC_CIPHER;
197201
198202 // Some |EVP_CIPHER|s take a variable-length key, and need to first be
199203 // configured with the key length, which requires configuring the cipher.
@@ -236,6 +240,12 @@ static void TestCipherAPI(const EVP_CIPHER *cipher, Operation op, bool padding,
236240 /* engine=*/ nullptr ,
237241 /* key=*/ nullptr , iv.data (), /* enc=*/ -1 ));
238242
243+ // Verify key commitment
244+ if (is_kc && !encrypt) {
245+ ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_VERIFY_KC,
246+ kc.size (), const_cast <uint8_t *>(kc.data ())));
247+ }
248+
239249 // CCM requires the full length of the plaintext to be known ahead of time.
240250 if (is_ccm) {
241251 int len;
@@ -358,8 +368,17 @@ static void TestCipherAPI(const EVP_CIPHER *cipher, Operation op, bool padding,
358368 ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_GET_TAG,
359369 tag.size (), rtag));
360370 EXPECT_EQ (Bytes (tag), Bytes (rtag, tag.size ()));
371+ }
372+
373+ if (encrypt & is_kc) {
374+ uint8_t rkc[32 ];
375+ ASSERT_LE (kc.size (), sizeof (rkc));
376+ ASSERT_TRUE (MaybeCopyCipherContext (copy, &ctx));
377+ ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_GET_KC,
378+ kc.size (), rkc));
379+ EXPECT_EQ (Bytes (kc), Bytes (rkc, kc.size ()));
361380 }
362- }
381+ }
363382}
364383
365384static void TestLowLevelAPI (
@@ -457,7 +476,8 @@ static void TestCipher(const EVP_CIPHER *cipher, Operation input_op,
457476 bssl::Span<const uint8_t > plaintext,
458477 bssl::Span<const uint8_t > ciphertext,
459478 bssl::Span<const uint8_t > aad,
460- bssl::Span<const uint8_t > tag) {
479+ bssl::Span<const uint8_t > tag,
480+ bssl::Span<const uint8_t > kc = {}) {
461481 size_t block_size = EVP_CIPHER_block_size (cipher);
462482 bool is_ccm = EVP_CIPHER_mode (cipher) == EVP_CIPH_CCM_MODE;
463483 std::vector<Operation> ops;
@@ -487,11 +507,11 @@ static void TestCipher(const EVP_CIPHER *cipher, Operation input_op,
487507 SCOPED_TRACE (copy);
488508 TestCipherAPI (cipher, op, padding, copy, in_place,
489509 /* use_evp_cipher=*/ false , chunk_size, key, iv,
490- plaintext, ciphertext, aad, tag);
510+ plaintext, ciphertext, aad, tag, kc );
491511 if (!padding && chunk_size % block_size == 0 ) {
492512 TestCipherAPI (cipher, op, padding, copy, in_place,
493513 /* use_evp_cipher=*/ true , chunk_size, key, iv,
494- plaintext, ciphertext, aad, tag);
514+ plaintext, ciphertext, aad, tag, kc );
495515 }
496516 }
497517 if (!padding) {
@@ -509,7 +529,7 @@ static void CipherFileTest(FileTest *t) {
509529 const EVP_CIPHER *cipher = GetCipher (cipher_str);
510530 ASSERT_TRUE (cipher);
511531
512- std::vector<uint8_t > key, iv, plaintext, ciphertext, aad, tag;
532+ std::vector<uint8_t > key, iv, plaintext, ciphertext, aad, tag, kc ;
513533 // Force an allocation of the underlying data-store so that v.data() is
514534 // non-NULL even for empty test vectors.
515535 plaintext.reserve (1 );
@@ -525,6 +545,10 @@ static void CipherFileTest(FileTest *t) {
525545 ASSERT_TRUE (t->GetBytes (&tag, " Tag" ));
526546 }
527547
548+ if (EVP_CIPHER_flags (cipher) & EVP_CIPH_FLAG_KC_CIPHER) {
549+ ASSERT_TRUE (t->GetBytes (&kc, " KC" ));
550+ }
551+
528552 Operation op = Operation::kBoth ;
529553 if (t->HasAttribute (" Operation" )) {
530554 const std::string &str = t->GetAttributeOrDie (" Operation" );
@@ -540,7 +564,7 @@ static void CipherFileTest(FileTest *t) {
540564 }
541565
542566 TestCipher (cipher, op, /* padding=*/ false , key, iv, plaintext, ciphertext, aad,
543- tag);
567+ tag, kc );
544568}
545569
546570TEST (CipherTest, TestVectors) {
@@ -1084,6 +1108,7 @@ TEST(CipherTest, GetCipher) {
10841108 test_get_cipher (NID_aes_256_ecb, " aes-256-ecb" );
10851109 test_get_cipher (NID_aes_256_gcm, " aes-256-gcm" );
10861110 test_get_cipher (NID_xaes_256_gcm, " xaes-256-gcm" );
1111+ test_get_cipher (NID_xaes_256_gcm_kc, " id-xaes256-gcm-kc" );
10871112 test_get_cipher (NID_aes_256_ofb128, " aes-256-ofb" );
10881113 test_get_cipher (NID_aes_256_xts, " aes-256-xts" );
10891114 test_get_cipher (NID_chacha20_poly1305, " chacha20-poly1305" );
@@ -1461,38 +1486,44 @@ TEST(CipherTest, Empty_EVP_CIPHER_CTX_V1187459157) {
14611486}
14621487
14631488TEST (CipherTest, XAES_256_GCM_EVP_CIPHER_INVALID_NONCE_KEY_LENGTH) {
1464- std::vector<uint8_t > key (32 ), nonce (24 );
1465-
1466- // XAES-256-GCM Encryption
1467- bssl::UniquePtr<EVP_CIPHER_CTX> ctx (EVP_CIPHER_CTX_new ());
1468- ASSERT_TRUE (ctx);
1469- ASSERT_TRUE (EVP_CipherInit_ex (ctx.get (), EVP_xaes_256_gcm (), nullptr , nullptr , nullptr , 1 ));
1470-
1471- // Valid nonce size: 20 bytes <= |N| <= 24 bytes
1472- // Test invalid nonce size
1473- ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_SET_IVLEN, 19 , nullptr ));
1474- ASSERT_FALSE (EVP_CipherInit_ex (ctx.get (), nullptr , nullptr , key.data (), nonce.data (), -1 ));
1475- ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_SET_IVLEN, 25 , nullptr ));
1476- ASSERT_FALSE (EVP_CipherInit_ex (ctx.get (), nullptr , nullptr , key.data (), nonce.data (), -1 ));
1477- ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_SET_IVLEN, 24 , nullptr ));
1478-
1479- // Valid key length: 32 bytes
1480- // Test invalid key length
1481- ctx.get ()->key_len = 24 ;
1482- ASSERT_FALSE (EVP_CipherInit_ex (ctx.get (), nullptr , nullptr , key.data (), nonce.data (), -1 ));
1483-
1484- ctx.get ()->key_len = 32 ;
1485- ASSERT_TRUE (EVP_CipherInit_ex (ctx.get (), nullptr , nullptr , key.data (), nonce.data (), -1 ));
1486-
1487- // EVP_CipherUpdate is not allowed after EVP_CipherFinal_ex
1488- std::vector<uint8_t > plaintext (1 ), ciphertext (1 );
1489- int plaintext_len = 1 , ciphertext_len = 0 ;
1490- ASSERT_TRUE (EVP_CipherUpdate (ctx.get (), ciphertext.data (), &ciphertext_len,
1491- plaintext.data (), plaintext_len));
1492- int len = 0 ;
1493- ASSERT_TRUE (EVP_CipherFinal_ex (ctx.get (), ciphertext.data () + ciphertext_len, &len));
1494- ASSERT_FALSE (EVP_CipherUpdate (ctx.get (), ciphertext.data (), &ciphertext_len,
1495- plaintext.data (), plaintext_len));
1489+ const auto test = [](const EVP_CIPHER *cipher) {
1490+ std::vector<uint8_t > key (32 ), nonce (24 );
1491+
1492+ bssl::UniquePtr<EVP_CIPHER_CTX> ctx (EVP_CIPHER_CTX_new ());
1493+ ASSERT_TRUE (ctx);
1494+ ASSERT_TRUE (EVP_CipherInit_ex (ctx.get (), cipher, nullptr , nullptr , nullptr , 1 ));
1495+
1496+ // Valid nonce size: 20 bytes <= |N| <= 24 bytes
1497+ // Test invalid nonce size
1498+ ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_SET_IVLEN, 19 , nullptr ));
1499+ ASSERT_FALSE (EVP_CipherInit_ex (ctx.get (), nullptr , nullptr , key.data (), nonce.data (), -1 ));
1500+ ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_SET_IVLEN, 25 , nullptr ));
1501+ ASSERT_FALSE (EVP_CipherInit_ex (ctx.get (), nullptr , nullptr , key.data (), nonce.data (), -1 ));
1502+ ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ctx.get (), EVP_CTRL_AEAD_SET_IVLEN, 24 , nullptr ));
1503+
1504+ // Valid key length: 32 bytes
1505+ // Test invalid key length
1506+ ctx.get ()->key_len = 24 ;
1507+ ASSERT_FALSE (EVP_CipherInit_ex (ctx.get (), nullptr , nullptr , key.data (), nonce.data (), -1 ));
1508+
1509+ ctx.get ()->key_len = 32 ;
1510+ ASSERT_TRUE (EVP_CipherInit_ex (ctx.get (), nullptr , nullptr , key.data (), nonce.data (), -1 ));
1511+
1512+ // EVP_CipherUpdate is not allowed after EVP_CipherFinal_ex
1513+ std::vector<uint8_t > plaintext (1 ), ciphertext (1 );
1514+ int plaintext_len = 1 , ciphertext_len = 0 ;
1515+ ASSERT_TRUE (EVP_CipherUpdate (ctx.get (), ciphertext.data (), &ciphertext_len,
1516+ plaintext.data (), plaintext_len));
1517+ int len = 0 ;
1518+ ASSERT_TRUE (EVP_CipherFinal_ex (ctx.get (), ciphertext.data () + ciphertext_len, &len));
1519+ ASSERT_FALSE (EVP_CipherUpdate (ctx.get (), ciphertext.data (), &ciphertext_len,
1520+ plaintext.data (), plaintext_len));
1521+ };
1522+
1523+ // XAES-256-GCM
1524+ test (EVP_xaes_256_gcm ());
1525+ // XAES-256-GCM-KC
1526+ test (EVP_xaes_256_gcm_kc ());
14961527}
14971528
14981529TEST (CipherTest, XAES_256_GCM_EVP_CIPHER_DERIVING_SUBKEYS_DIFFERENT_NONCES) {
@@ -1560,8 +1591,6 @@ TEST(CipherTest, XAES_256_GCM_EVP_CIPHER_DERIVING_SUBKEYS_DIFFERENT_NONCES) {
15601591 decrypted.resize (ciphertext_len);
15611592 int decrypted_len = 0 ;
15621593
1563- ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (dctx.get (), EVP_CTRL_AEAD_SET_TAG, tag.size (), tag.data ()));
1564-
15651594 // ASSERT_TRUE(EVP_DecryptUpdate(dctx.get(), decrypted.data(), &decrypted_len, ciphertext.data(), ciphertext_len));
15661595 for (size_t i = 0 ; i < plaintext_len; ++i) {
15671596 // Test streaming input
@@ -1570,6 +1599,7 @@ TEST(CipherTest, XAES_256_GCM_EVP_CIPHER_DERIVING_SUBKEYS_DIFFERENT_NONCES) {
15701599 decrypted_len += len;
15711600 }
15721601
1602+ ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (dctx.get (), EVP_CTRL_AEAD_SET_TAG, tag.size (), tag.data ()));
15731603 ASSERT_TRUE (EVP_DecryptFinal (dctx.get (), decrypted.data () + decrypted_len, &len));
15741604 decrypted_len += len;
15751605
@@ -1647,13 +1677,12 @@ TEST(CipherTest, XAES_256_GCM_EVP_CIPHER_MULTI_LOOP_TEST) {
16471677
16481678 // XAES-256-GCM Decryption
16491679 ASSERT_TRUE (EVP_DecryptInit_ex (dctx.get (), nullptr , nullptr , key.data (), nonce.data ()));
1650- ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (dctx.get (), EVP_CTRL_AEAD_SET_TAG, tag_size, tag.data ()));
1651-
16521680 std::vector<uint8_t > decrypted;
16531681 decrypted.resize (plaintext_len);
16541682 len = 0 ;
16551683 EVP_DecryptUpdate (dctx.get (), nullptr , &len, aad.data (), aad_len);
16561684 ASSERT_TRUE (EVP_DecryptUpdate (dctx.get (), decrypted.data (), &len, ciphertext.data (), ciphertext_len));
1685+ ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (dctx.get (), EVP_CTRL_AEAD_SET_TAG, tag_size, tag.data ()));
16571686 ASSERT_TRUE (EVP_DecryptFinal (dctx.get (), decrypted.data () + len, &len));
16581687
16591688 ASSERT_EQ (Bytes (decrypted), Bytes (plaintext.data (), plaintext_len));
@@ -1670,27 +1699,28 @@ TEST(CipherTest, XAES_256_GCM_EVP_CIPHER_MULTI_LOOP_TEST) {
16701699}
16711700
16721701TEST (CipherTest, XAES_256_GCM_EVP_CIPHER_SHORTER_NONCE) {
1673- std::vector<uint8_t > key;
1674-
1675- /* ============ INITIALIZE ENCRYPTION CONTEXT ============ */
1676- bssl::UniquePtr<EVP_CIPHER_CTX> ectx (EVP_CIPHER_CTX_new ());
1677- ASSERT_TRUE (ectx);
1678- ASSERT_TRUE (EVP_CipherInit_ex (ectx.get (), EVP_xaes_256_gcm (), nullptr , nullptr , nullptr , 1 ));
1679-
1680- // Initialize the main key
1681- DecodeHex (&key, " 0101010101010101010101010101010101010101010101010101010101010101" );
1682- ASSERT_TRUE (EVP_CipherInit_ex (ectx.get (), nullptr , nullptr , key.data (), nullptr , -1 ));
1683-
1684- /* ============ INITIALIZE DECRYPTION CONTEXT ============ */
1685- bssl::UniquePtr<EVP_CIPHER_CTX> dctx (EVP_CIPHER_CTX_new ());
1686- ASSERT_TRUE (dctx);
1687- ASSERT_TRUE (EVP_DecryptInit_ex (dctx.get (), EVP_xaes_256_gcm (), nullptr , nullptr , nullptr ));
1688-
1689- // Initialize the main key
1690- ASSERT_TRUE (EVP_DecryptInit_ex (dctx.get (), nullptr , nullptr , key.data (), nullptr ));
1691-
16921702 // Test encryption and decryption
1693- const auto test = [&ectx, &dctx](std::vector<uint8_t > &iv, int iv_len, const uint8_t *plaintext, size_t plaintext_len) {
1703+ const auto test = [](const EVP_CIPHER *cipher, std::vector<uint8_t > &iv, int iv_len,
1704+ const uint8_t *plaintext, size_t plaintext_len) {
1705+ std::vector<uint8_t > key;
1706+
1707+ /* ============ INITIALIZE ENCRYPTION CONTEXT ============ */
1708+ bssl::UniquePtr<EVP_CIPHER_CTX> ectx (EVP_CIPHER_CTX_new ());
1709+ ASSERT_TRUE (ectx);
1710+ ASSERT_TRUE (EVP_CipherInit_ex (ectx.get (), cipher, nullptr , nullptr , nullptr , 1 ));
1711+
1712+ // Initialize the main key
1713+ DecodeHex (&key, " 0101010101010101010101010101010101010101010101010101010101010101" );
1714+ ASSERT_TRUE (EVP_CipherInit_ex (ectx.get (), nullptr , nullptr , key.data (), nullptr , -1 ));
1715+
1716+ /* ============ INITIALIZE DECRYPTION CONTEXT ============ */
1717+ bssl::UniquePtr<EVP_CIPHER_CTX> dctx (EVP_CIPHER_CTX_new ());
1718+ ASSERT_TRUE (dctx);
1719+ ASSERT_TRUE (EVP_DecryptInit_ex (dctx.get (), cipher, nullptr , nullptr , nullptr ));
1720+
1721+ // Initialize the main key
1722+ ASSERT_TRUE (EVP_DecryptInit_ex (dctx.get (), nullptr , nullptr , key.data (), nullptr ));
1723+
16941724 // Set IV Length
16951725 ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (ectx.get (), EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr ));
16961726 ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (dctx.get (), EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr ));
@@ -1720,9 +1750,8 @@ TEST(CipherTest, XAES_256_GCM_EVP_CIPHER_SHORTER_NONCE) {
17201750 std::vector<uint8_t > decrypted;
17211751 decrypted.resize (ciphertext_len);
17221752 int decrypted_len = 0 ;
1723-
1724- ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (dctx.get (), EVP_CTRL_AEAD_SET_TAG, tag.size (), tag.data ()));
17251753 ASSERT_TRUE (EVP_DecryptUpdate (dctx.get (), decrypted.data (), &decrypted_len, ciphertext.data (), ciphertext_len));
1754+ ASSERT_TRUE (EVP_CIPHER_CTX_ctrl (dctx.get (), EVP_CTRL_AEAD_SET_TAG, tag.size (), tag.data ()));
17261755 ASSERT_TRUE (EVP_DecryptFinal (dctx.get (), decrypted.data () + decrypted_len, &len));
17271756 decrypted_len += len;
17281757
@@ -1735,10 +1764,12 @@ TEST(CipherTest, XAES_256_GCM_EVP_CIPHER_SHORTER_NONCE) {
17351764 DecodeHex (&iv, " 4242424242424242424242424242424242424242" );
17361765 const uint8_t *plaintext = (const uint8_t *)" Hello, XAES-256-GCM!" ;
17371766 std::vector<uint8_t > ciphertext, tag;
1738- test (iv, iv.size (), plaintext, strlen ((const char *)plaintext));
1767+ test (EVP_xaes_256_gcm (), iv, iv.size (), plaintext, strlen ((const char *)plaintext));
1768+ test (EVP_xaes_256_gcm_kc (), iv, iv.size (), plaintext, strlen ((const char *)plaintext));
17391769
17401770 // Test with a 23-byte IV
17411771 DecodeHex (&iv, " 4142434445464748494a4b4c4d4e4f5051525354555657" );
17421772 plaintext = (const uint8_t *)" XAES-256-GCM" ;
1743- test (iv, iv.size (), plaintext, strlen ((const char *)plaintext));
1773+ test (EVP_xaes_256_gcm (), iv, iv.size (), plaintext, strlen ((const char *)plaintext));
1774+ test (EVP_xaes_256_gcm_kc (), iv, iv.size (), plaintext, strlen ((const char *)plaintext));
17441775}
0 commit comments