Skip to content

Commit 6d0c704

Browse files
authored
Implementation of XAES-256-GCM with EVP_CIPHER (#2750)
Add XAES-256-GCM, which is extended AES-256-GCM with a derived key mode proposed by Filippo Valsorda in 2023, followed by a specification released in 2024. This implementation supports EVP_CIPHER API, allows configuration to use either FIPS-compliant CMAC available in AWS-LC, or an optimized CMAC dedicated to the specific use case of XAES-256-GCM from XAES-256-GCM #2652. Support varying nonce sizes: 20 ≤ b ≤ 24 based on the extension: https://eprint.iacr.org/2025/758.pdf#page=24
1 parent 0fed4db commit 6d0c704

File tree

12 files changed

+534
-16
lines changed

12 files changed

+534
-16
lines changed

crypto/cipher_extra/cipher_extra.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ static const struct {
8989
{NID_aes_256_ctr, "aes-256-ctr", EVP_aes_256_ctr},
9090
{NID_aes_256_ecb, "aes-256-ecb", EVP_aes_256_ecb},
9191
{NID_aes_256_gcm, "aes-256-gcm", EVP_aes_256_gcm},
92+
{NID_xaes_256_gcm, "xaes-256-gcm", EVP_xaes_256_gcm},
9293
{NID_aes_256_ofb128, "aes-256-ofb", EVP_aes_256_ofb},
9394
{NID_aes_256_xts, "aes-256-xts", EVP_aes_256_xts},
9495
{NID_chacha20_poly1305, "chacha20-poly1305", EVP_chacha20_poly1305},
@@ -114,7 +115,8 @@ static const struct {
114115
{"aes128", "aes-128-cbc"},
115116
{"id-aes128-gcm", "aes-128-gcm"},
116117
{"id-aes192-gcm", "aes-192-gcm"},
117-
{"id-aes256-gcm", "aes-256-gcm"}
118+
{"id-aes256-gcm", "aes-256-gcm"},
119+
{"id-xaes256-gcm", "xaes-256-gcm"}
118120
};
119121

120122
const EVP_CIPHER *EVP_get_cipherbynid(int nid) {

crypto/cipher_extra/cipher_test.cc

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
#include <openssl/rand.h>
6969
#include <openssl/sha.h>
7070
#include <openssl/span.h>
71+
#include <openssl/digest.h>
7172

7273
#include "../internal.h"
7374
#include "../test/file_test.h"
@@ -127,6 +128,8 @@ static const EVP_CIPHER *GetCipher(const std::string &name) {
127128
return EVP_aes_192_ccm();
128129
} else if (name == "AES-256-CCM") {
129130
return EVP_aes_256_ccm();
131+
} else if (name == "XAES-256-GCM") {
132+
return EVP_xaes_256_gcm();
130133
}
131134
return nullptr;
132135
}
@@ -1080,6 +1083,7 @@ TEST(CipherTest, GetCipher) {
10801083
test_get_cipher(NID_aes_256_ctr, "aes-256-ctr");
10811084
test_get_cipher(NID_aes_256_ecb, "aes-256-ecb");
10821085
test_get_cipher(NID_aes_256_gcm, "aes-256-gcm");
1086+
test_get_cipher(NID_xaes_256_gcm, "xaes-256-gcm");
10831087
test_get_cipher(NID_aes_256_ofb128, "aes-256-ofb");
10841088
test_get_cipher(NID_aes_256_xts, "aes-256-xts");
10851089
test_get_cipher(NID_chacha20_poly1305, "chacha20-poly1305");
@@ -1102,6 +1106,7 @@ TEST(CipherTest, GetCipher) {
11021106
test_get_cipher(NID_aes_128_gcm, "id-aes128-gcm");
11031107
test_get_cipher(NID_aes_192_gcm, "id-aes192-gcm");
11041108
test_get_cipher(NID_aes_256_gcm, "id-aes256-gcm");
1109+
test_get_cipher(NID_xaes_256_gcm, "id-xaes256-gcm");
11051110

11061111
// error case
11071112
EXPECT_FALSE(EVP_get_cipherbyname(nullptr));
@@ -1454,3 +1459,286 @@ TEST(CipherTest, Empty_EVP_CIPHER_CTX_V1187459157) {
14541459
CHECK_ERROR(EVP_DecryptUpdate(ctx.get(), out_vec.data(), &out_len, in_vec.data(), in_len), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
14551460
CHECK_ERROR(EVP_DecryptFinal(ctx.get(), out_vec.data(), &out_len), ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
14561461
}
1462+
1463+
TEST(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));
1496+
}
1497+
1498+
TEST(CipherTest, XAES_256_GCM_EVP_CIPHER_DERIVING_SUBKEYS_DIFFERENT_NONCES) {
1499+
/*
1500+
* Test deriving many subkeys from a main key but with different nonces
1501+
* Source of test vectors:
1502+
* https://github.com/C2SP/C2SP/blob/main/XAES-256-GCM.md
1503+
*/
1504+
std::vector<uint8_t> key;
1505+
1506+
/* ============ INITIALIZE ENCRYPTION CONTEXT ============ */
1507+
bssl::UniquePtr<EVP_CIPHER_CTX> ectx(EVP_CIPHER_CTX_new());
1508+
ASSERT_TRUE(ectx);
1509+
ASSERT_TRUE(EVP_CipherInit_ex(ectx.get(), EVP_xaes_256_gcm(), nullptr, nullptr, nullptr, 1));
1510+
size_t iv_len = 24;
1511+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ectx.get(), EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr));
1512+
1513+
// Initialize the main key
1514+
DecodeHex(&key, "0101010101010101010101010101010101010101010101010101010101010101");
1515+
ASSERT_TRUE(EVP_CipherInit_ex(ectx.get(), nullptr, nullptr, key.data(), nullptr, -1));
1516+
1517+
/* ============ INITIALIZE DECRYPTION CONTEXT ============ */
1518+
bssl::UniquePtr<EVP_CIPHER_CTX> dctx(EVP_CIPHER_CTX_new());
1519+
ASSERT_TRUE(dctx);
1520+
ASSERT_TRUE(EVP_DecryptInit_ex(dctx.get(), EVP_xaes_256_gcm(), nullptr, nullptr, nullptr));
1521+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(dctx.get(), EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr));
1522+
1523+
// Initialize the main key
1524+
ASSERT_TRUE(EVP_DecryptInit_ex(dctx.get(), nullptr, nullptr, key.data(), nullptr));
1525+
1526+
// Test encryption and decryption
1527+
const auto test = [&ectx, &dctx](std::vector<uint8_t> &iv, const uint8_t *plaintext, size_t plaintext_len,
1528+
std::vector<uint8_t> &expected_ciphertext, std::vector<uint8_t> &expected_tag) {
1529+
// Encrypt
1530+
// Initiaze IV and derive a subkey
1531+
ASSERT_TRUE(EVP_CipherInit_ex(ectx.get(), nullptr, nullptr, nullptr, iv.data(), -1));
1532+
1533+
std::vector<uint8_t> ciphertext, tag;
1534+
ciphertext.resize(plaintext_len);
1535+
int ciphertext_len = 0, len = 0;
1536+
1537+
// ASSERT_TRUE(EVP_CipherUpdate(ectx.get(), ciphertext.data(), &ciphertext_len, plaintext, plaintext_len));
1538+
1539+
for(size_t i = 0; i < plaintext_len; ++i) {
1540+
// Test streaming input
1541+
ASSERT_TRUE(EVP_CipherUpdate(ectx.get(), ciphertext.data() + ciphertext_len, &len,
1542+
plaintext + i, /* one byte */ 1));
1543+
ciphertext_len += len;
1544+
}
1545+
1546+
ASSERT_TRUE(EVP_CipherFinal_ex(ectx.get(), ciphertext.data() + ciphertext_len, &len));
1547+
ciphertext_len += len;
1548+
ASSERT_EQ(Bytes(ciphertext), Bytes(expected_ciphertext));
1549+
1550+
size_t tag_size = 16;
1551+
tag.resize(tag_size);
1552+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ectx.get(), EVP_CTRL_AEAD_GET_TAG, tag.size(), (void*)tag.data()));
1553+
ASSERT_EQ(Bytes(tag), Bytes(expected_tag));
1554+
1555+
// Decrypt
1556+
// Initiaze IV and derive a subkey
1557+
ASSERT_TRUE(EVP_DecryptInit_ex(dctx.get(), nullptr, nullptr, nullptr, iv.data()));
1558+
1559+
std::vector<uint8_t> decrypted;
1560+
decrypted.resize(ciphertext_len);
1561+
int decrypted_len = 0;
1562+
1563+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(dctx.get(), EVP_CTRL_AEAD_SET_TAG, tag.size(), tag.data()));
1564+
1565+
// ASSERT_TRUE(EVP_DecryptUpdate(dctx.get(), decrypted.data(), &decrypted_len, ciphertext.data(), ciphertext_len));
1566+
for(size_t i = 0; i < plaintext_len; ++i) {
1567+
// Test streaming input
1568+
ASSERT_TRUE(EVP_DecryptUpdate(dctx.get(), decrypted.data() + decrypted_len, &len,
1569+
ciphertext.data() + i, /* one byte */ 1));
1570+
decrypted_len += len;
1571+
}
1572+
1573+
ASSERT_TRUE(EVP_DecryptFinal(dctx.get(), decrypted.data() + decrypted_len, &len));
1574+
decrypted_len += len;
1575+
1576+
ASSERT_EQ((size_t)decrypted_len, plaintext_len);
1577+
ASSERT_EQ(Bytes(decrypted), Bytes(plaintext, plaintext_len));
1578+
};
1579+
1580+
// Test with an IV
1581+
std::vector<uint8_t> iv;
1582+
DecodeHex(&iv, "424242424242424242424242424242424242424242424242");
1583+
1584+
// Test encryption and decryption with a plaintext
1585+
const uint8_t *plaintext = (const uint8_t *)"Hello, XAES-256-GCM!";
1586+
std::vector<uint8_t> ciphertext, tag;
1587+
DecodeHex(&ciphertext, "01e5f78bc99de880bd2eeff2870d361f0eab5b2f");
1588+
DecodeHex(&tag, "c55268f34b14045878fe3668db980319");
1589+
test(iv, plaintext, strlen((const char *)plaintext), ciphertext, tag);
1590+
1591+
// Test with another IV
1592+
DecodeHex(&iv, "4142434445464748494a4b4c4d4e4f505152535455565758");
1593+
1594+
// Test encryption and decryption again with another plaintext
1595+
plaintext = (const uint8_t *)"XAES-256-GCM";
1596+
DecodeHex(&ciphertext, "ce546ef63c9cc60765923609");
1597+
DecodeHex(&tag, "b33a9a1974e96e52daf2fcf7075e2271");
1598+
test(iv, plaintext, strlen((const char *)plaintext), ciphertext, tag);
1599+
}
1600+
1601+
TEST(CipherTest, XAES_256_GCM_EVP_CIPHER_MULTI_LOOP_TEST) {
1602+
// Source of multi-loop tests:
1603+
// https://github.com/C2SP/C2SP/blob/main/XAES-256-GCM/go/XAES-256-GCM_test.go
1604+
const auto test = [](int n, const char *output) {
1605+
bssl::ScopedEVP_MD_CTX s;
1606+
ASSERT_TRUE(EVP_DigestInit(s.get(), EVP_shake128()));
1607+
bssl::ScopedEVP_MD_CTX d;
1608+
ASSERT_TRUE(EVP_DigestInit(d.get(), EVP_shake128()));
1609+
1610+
bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
1611+
ASSERT_TRUE(ctx);
1612+
ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), EVP_xaes_256_gcm(), nullptr, nullptr, nullptr, 1));
1613+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_SET_IVLEN, 24, nullptr));
1614+
1615+
bssl::UniquePtr<EVP_CIPHER_CTX> dctx(EVP_CIPHER_CTX_new());
1616+
ASSERT_TRUE(dctx);
1617+
ASSERT_TRUE(EVP_DecryptInit_ex(dctx.get(), EVP_xaes_256_gcm(), nullptr, nullptr, nullptr));
1618+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(dctx.get(), EVP_CTRL_AEAD_SET_IVLEN, 24, nullptr));
1619+
1620+
std::vector<uint8_t> key(32), nonce(24), plaintext(256);
1621+
std::vector<uint8_t> aad(256), ciphertext(256), tag(16);
1622+
uint8_t plaintext_len = 0, aad_len = 0;
1623+
int tag_size = 16;
1624+
1625+
for(int i = 0; i < n; ++i) {
1626+
ASSERT_TRUE(EVP_DigestSqueeze(s.get(), key.data(), 32));
1627+
ASSERT_TRUE(EVP_DigestSqueeze(s.get(), nonce.data(), 24));
1628+
ASSERT_TRUE(EVP_DigestSqueeze(s.get(), &plaintext_len, 1));
1629+
ASSERT_TRUE(EVP_DigestSqueeze(s.get(), plaintext.data(), plaintext_len));
1630+
ASSERT_TRUE(EVP_DigestSqueeze(s.get(), &aad_len, 1));
1631+
ASSERT_TRUE(EVP_DigestSqueeze(s.get(), aad.data(), aad_len));
1632+
1633+
// XAES-256-GCM Encryption
1634+
ASSERT_TRUE(EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, key.data(), nonce.data(), -1));
1635+
ASSERT_EQ(aad_len, EVP_Cipher(ctx.get(), nullptr, aad.data(), aad_len));
1636+
int ciphertext_len = 0;
1637+
ASSERT_TRUE(EVP_CipherUpdate(ctx.get(), ciphertext.data(), &ciphertext_len,
1638+
plaintext.data(), plaintext_len));
1639+
1640+
int len = 0;
1641+
ASSERT_TRUE(EVP_CipherFinal_ex(ctx.get(), ciphertext.data() + ciphertext_len, &len));
1642+
ciphertext_len += len;
1643+
ASSERT_TRUE(EVP_DigestUpdate(d.get(), ciphertext.data(), ciphertext_len));
1644+
1645+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_AEAD_GET_TAG, tag_size, tag.data()));
1646+
ASSERT_TRUE(EVP_DigestUpdate(d.get(), tag.data(), tag_size));
1647+
1648+
// XAES-256-GCM Decryption
1649+
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+
1652+
std::vector<uint8_t> decrypted;
1653+
decrypted.resize(plaintext_len);
1654+
len = 0;
1655+
EVP_DecryptUpdate(dctx.get(), nullptr, &len, aad.data(), aad_len);
1656+
ASSERT_TRUE(EVP_DecryptUpdate(dctx.get(), decrypted.data(), &len, ciphertext.data(), ciphertext_len));
1657+
ASSERT_TRUE(EVP_DecryptFinal(dctx.get(), decrypted.data() + len, &len));
1658+
1659+
ASSERT_EQ(Bytes(decrypted), Bytes(plaintext.data(), plaintext_len));
1660+
}
1661+
std::vector<uint8_t> expected;
1662+
ASSERT_TRUE(DecodeHex(&expected, output));
1663+
uint8_t got[32] = {0};
1664+
ASSERT_TRUE(EVP_DigestFinalXOF(d.get(), got, 32));
1665+
ASSERT_EQ(Bytes(got, 32), Bytes(expected));
1666+
};
1667+
1668+
test(10000, "e6b9edf2df6cec60c8cbd864e2211b597fb69a529160cd040d56c0c210081939");
1669+
test(1000000, "2163ae1445985a30b60585ee67daa55674df06901b890593e824b8a7c885ab15");
1670+
}
1671+
1672+
TEST(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+
1692+
// 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) {
1694+
// Set IV Length
1695+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ectx.get(), EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr));
1696+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(dctx.get(), EVP_CTRL_AEAD_SET_IVLEN, iv_len, nullptr));
1697+
1698+
// Encrypt
1699+
// Initiaze IV and derive a subkey
1700+
ASSERT_TRUE(EVP_CipherInit_ex(ectx.get(), nullptr, nullptr, nullptr, iv.data(), -1));
1701+
1702+
std::vector<uint8_t> ciphertext, tag;
1703+
ciphertext.resize(plaintext_len);
1704+
int ciphertext_len = 0;
1705+
1706+
ASSERT_TRUE(EVP_CipherUpdate(ectx.get(), ciphertext.data(), &ciphertext_len,
1707+
plaintext, plaintext_len));
1708+
int len = 0;
1709+
ASSERT_TRUE(EVP_CipherFinal_ex(ectx.get(), ciphertext.data() + ciphertext_len, &len));
1710+
ciphertext_len += len;
1711+
1712+
size_t tag_size = 16;
1713+
tag.resize(tag_size);
1714+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(ectx.get(), EVP_CTRL_AEAD_GET_TAG, tag.size(), (void*)tag.data()));
1715+
1716+
// Decrypt
1717+
// Initiaze IV and derive a subkey
1718+
ASSERT_TRUE(EVP_DecryptInit_ex(dctx.get(), nullptr, nullptr, nullptr, iv.data()));
1719+
1720+
std::vector<uint8_t> decrypted;
1721+
decrypted.resize(ciphertext_len);
1722+
int decrypted_len = 0;
1723+
1724+
ASSERT_TRUE(EVP_CIPHER_CTX_ctrl(dctx.get(), EVP_CTRL_AEAD_SET_TAG, tag.size(), tag.data()));
1725+
ASSERT_TRUE(EVP_DecryptUpdate(dctx.get(), decrypted.data(), &decrypted_len, ciphertext.data(), ciphertext_len));
1726+
ASSERT_TRUE(EVP_DecryptFinal(dctx.get(), decrypted.data() + decrypted_len, &len));
1727+
decrypted_len += len;
1728+
1729+
ASSERT_EQ((size_t)decrypted_len, plaintext_len);
1730+
ASSERT_EQ(Bytes(decrypted), Bytes(plaintext, plaintext_len));
1731+
};
1732+
1733+
// Test with a 20-byte IV
1734+
std::vector<uint8_t> iv;
1735+
DecodeHex(&iv, "4242424242424242424242424242424242424242");
1736+
const uint8_t *plaintext = (const uint8_t *)"Hello, XAES-256-GCM!";
1737+
std::vector<uint8_t> ciphertext, tag;
1738+
test(iv, iv.size(), plaintext, strlen((const char *)plaintext));
1739+
1740+
// Test with a 23-byte IV
1741+
DecodeHex(&iv, "4142434445464748494a4b4c4d4e4f5051525354555657");
1742+
plaintext = (const uint8_t *)"XAES-256-GCM";
1743+
test(iv, iv.size(), plaintext, strlen((const char *)plaintext));
1744+
}

crypto/cipher_extra/test/cipher_tests.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,32 @@ AAD = feedfacedeadbeeffeedfacedeadbeefabaddad2
506506
Tag = a44a8266ee1c8eb0c8b5d4cf5ae9f19b
507507
Operation = InvalidDecrypt
508508

509+
# Source of test vectors:
510+
# https://github.com/C2SP/C2SP/blob/main/XAES-256-GCM.md
511+
Cipher = XAES-256-GCM
512+
Key = 0101010101010101010101010101010101010101010101010101010101010101
513+
IV = 424242424242424242424242424242424242424242424242
514+
Plaintext = 48656c6c6f2c20584145532d3235362d47434d21
515+
Ciphertext = 01e5f78bc99de880bd2eeff2870d361f0eab5b2f
516+
AAD =
517+
Tag = c55268f34b14045878fe3668db980319
518+
519+
Cipher = XAES-256-GCM
520+
Key = 0101010101010101010101010101010101010101010101010101010101010101
521+
IV = 4142434445464748494a4b4c4d4e4f505152535455565758
522+
Plaintext = 584145532d3235362d47434d
523+
Ciphertext = ce546ef63c9cc60765923609
524+
AAD =
525+
Tag = b33a9a1974e96e52daf2fcf7075e2271
526+
527+
Cipher = XAES-256-GCM
528+
Key = 0303030303030303030303030303030303030303030303030303030303030303
529+
IV = 4142434445464748494a4b4c4d4e4f505152535455565758
530+
Plaintext = 584145532d3235362d47434d
531+
Ciphertext = 986ec1832593df5443a17943
532+
AAD = 633273702e6f72672f584145532d3235362d47434d
533+
Tag = 7fd083bf3fdb41abd740a21f71eb769d
534+
509535
# local add-ons, primarily streaming ghash tests
510536
# 128 bytes aad
511537
Cipher = AES-128-GCM

0 commit comments

Comments
 (0)