1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright 2026 Google LLC 4 */ 5 #include <crypto/aes-cbc-macs.h> 6 #include "aes-cmac-testvecs.h" 7 8 /* 9 * A fixed key used when presenting AES-CMAC as an unkeyed hash function in 10 * order to reuse hash-test-template.h. At the beginning of the test suite, 11 * this is initialized to a key prepared from bytes generated from a fixed seed. 12 */ 13 static struct aes_cmac_key test_key; 14 15 static void aes_cmac_init_withtestkey(struct aes_cmac_ctx *ctx) 16 { 17 aes_cmac_init(ctx, &test_key); 18 } 19 20 static void aes_cmac_withtestkey(const u8 *data, size_t data_len, 21 u8 out[AES_BLOCK_SIZE]) 22 { 23 aes_cmac(&test_key, data, data_len, out); 24 } 25 26 #define HASH aes_cmac_withtestkey 27 #define HASH_CTX aes_cmac_ctx 28 #define HASH_SIZE AES_BLOCK_SIZE 29 #define HASH_INIT aes_cmac_init_withtestkey 30 #define HASH_UPDATE aes_cmac_update 31 #define HASH_FINAL aes_cmac_final 32 #include "hash-test-template.h" 33 34 static int aes_cbc_macs_suite_init(struct kunit_suite *suite) 35 { 36 u8 raw_key[AES_KEYSIZE_256]; 37 38 rand_bytes_seeded_from_len(raw_key, sizeof(raw_key)); 39 return aes_cmac_preparekey(&test_key, raw_key, sizeof(raw_key)); 40 } 41 42 /* Verify compatibility of the AES-CMAC implementation with RFC 4493. */ 43 static void test_aes_cmac_rfc4493(struct kunit *test) 44 { 45 static const u8 raw_key[AES_KEYSIZE_128] = { 46 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 47 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, 48 }; 49 static const struct { 50 size_t data_len; 51 const u8 data[40]; 52 const u8 mac[AES_BLOCK_SIZE]; 53 } testvecs[] = { 54 { 55 /* Example 1 from RFC 4493 */ 56 .data_len = 0, 57 .mac = { 58 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 59 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46, 60 }, 61 62 }, 63 { 64 /* Example 2 from RFC 4493 */ 65 .data = { 66 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 67 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 68 }, 69 .data_len = 16, 70 .mac = { 71 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 72 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c, 73 }, 74 }, 75 { 76 /* Example 3 from RFC 4493 */ 77 .data = { 78 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 79 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 80 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 81 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 82 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 83 }, 84 .data_len = 40, 85 .mac = { 86 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 87 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27, 88 }, 89 }, 90 }; 91 struct aes_cmac_key key; 92 int err; 93 94 err = aes_cmac_preparekey(&key, raw_key, sizeof(raw_key)); 95 KUNIT_ASSERT_EQ(test, err, 0); 96 97 for (size_t i = 0; i < ARRAY_SIZE(testvecs); i++) { 98 u8 mac[AES_BLOCK_SIZE]; 99 100 aes_cmac(&key, testvecs[i].data, testvecs[i].data_len, mac); 101 KUNIT_ASSERT_MEMEQ(test, mac, testvecs[i].mac, AES_BLOCK_SIZE); 102 } 103 } 104 105 /* 106 * Verify compatibility of the AES-XCBC-MAC implementation with RFC 3566. 107 * 108 * Additional AES-XCBC-MAC tests are not necessary, since the AES-XCBC-MAC 109 * implementation is well covered by the AES-CMAC tests already. Only the key 110 * preparation function differs; the rest of the code is shared. 111 */ 112 static void test_aes_xcbcmac_rfc3566(struct kunit *test) 113 { 114 struct aes_cmac_key key; 115 /* AES-XCBC-MAC Test Case #4 from RFC 3566 */ 116 static const u8 raw_key[AES_KEYSIZE_128] = { 117 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 118 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 119 }; 120 static const u8 message[20] = { 121 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 122 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 123 }; 124 static const u8 expected_mac[AES_BLOCK_SIZE] = { 125 0x47, 0xf5, 0x1b, 0x45, 0x64, 0x96, 0x62, 0x15, 126 0xb8, 0x98, 0x5c, 0x63, 0x05, 0x5e, 0xd3, 0x08, 127 }; 128 u8 actual_mac[AES_BLOCK_SIZE]; 129 130 aes_xcbcmac_preparekey(&key, raw_key); 131 aes_cmac(&key, message, sizeof(message), actual_mac); 132 KUNIT_ASSERT_MEMEQ(test, actual_mac, expected_mac, AES_BLOCK_SIZE); 133 } 134 135 static void test_aes_cbcmac_rfc3610(struct kunit *test) 136 { 137 /* 138 * The following AES-CBC-MAC test vector is extracted from RFC 3610 139 * Packet Vector #11. It required some rearrangement to get the actual 140 * input to AES-CBC-MAC from the values given. 141 */ 142 static const u8 raw_key[AES_KEYSIZE_128] = { 143 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 144 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 145 }; 146 const size_t unpadded_data_len = 52; 147 static const u8 data[64] = { 148 /* clang-format off */ 149 /* CCM header */ 150 0x61, 0x00, 0x00, 0x00, 0x0d, 0x0c, 0x0b, 0x0a, 151 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0x00, 0x14, 152 /* CCM additional authentication blocks */ 153 0x00, 0x0c, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 154 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x00, 155 /* CCM message blocks */ 156 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 157 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 158 0x1c, 0x1d, 0x1e, 0x1f, 0x00, 0x00, 0x00, 0x00, 159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 160 /* clang-format on */ 161 }; 162 static const u8 expected_mac[AES_BLOCK_SIZE] = { 163 0x6b, 0x5e, 0x24, 0x34, 0x12, 0xcc, 0xc2, 0xad, 164 0x6f, 0x1b, 0x11, 0xc3, 0xa1, 0xa9, 0xd8, 0xbc, 165 }; 166 struct aes_enckey key; 167 struct aes_cbcmac_ctx ctx; 168 u8 actual_mac[AES_BLOCK_SIZE]; 169 int err; 170 171 err = aes_prepareenckey(&key, raw_key, sizeof(raw_key)); 172 KUNIT_ASSERT_EQ(test, err, 0); 173 174 /* 175 * Trailing zeroes should not affect the CBC-MAC value, up to the next 176 * AES block boundary. 177 */ 178 for (size_t data_len = unpadded_data_len; data_len <= sizeof(data); 179 data_len++) { 180 aes_cbcmac_init(&ctx, &key); 181 aes_cbcmac_update(&ctx, data, data_len); 182 aes_cbcmac_final(&ctx, actual_mac); 183 KUNIT_ASSERT_MEMEQ(test, actual_mac, expected_mac, 184 AES_BLOCK_SIZE); 185 186 /* Incremental computations should produce the same result. */ 187 for (size_t part1_len = 0; part1_len <= data_len; part1_len++) { 188 aes_cbcmac_init(&ctx, &key); 189 aes_cbcmac_update(&ctx, data, part1_len); 190 aes_cbcmac_update(&ctx, &data[part1_len], 191 data_len - part1_len); 192 aes_cbcmac_final(&ctx, actual_mac); 193 KUNIT_ASSERT_MEMEQ(test, actual_mac, expected_mac, 194 AES_BLOCK_SIZE); 195 } 196 } 197 } 198 199 static struct kunit_case aes_cbc_macs_test_cases[] = { 200 HASH_KUNIT_CASES, 201 KUNIT_CASE(test_aes_cmac_rfc4493), 202 KUNIT_CASE(test_aes_xcbcmac_rfc3566), 203 KUNIT_CASE(test_aes_cbcmac_rfc3610), 204 KUNIT_CASE(benchmark_hash), 205 {}, 206 }; 207 208 static struct kunit_suite aes_cbc_macs_test_suite = { 209 .name = "aes_cbc_macs", 210 .test_cases = aes_cbc_macs_test_cases, 211 .suite_init = aes_cbc_macs_suite_init, 212 }; 213 kunit_test_suite(aes_cbc_macs_test_suite); 214 215 MODULE_DESCRIPTION( 216 "KUnit tests and benchmark for AES-CMAC, AES-XCBC-MAC, and AES-CBC-MAC"); 217 MODULE_IMPORT_NS("CRYPTO_INTERNAL"); 218 MODULE_LICENSE("GPL"); 219