1 /* $NetBSD: aes_selftest.c,v 1.8 2025/12/22 16:35:34 nia Exp $ */ 2 3 /*- 4 * Copyright (c) 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(1, "$NetBSD: aes_selftest.c,v 1.8 2025/12/22 16:35:34 nia Exp $"); 31 32 #ifdef _KERNEL 33 34 #include <sys/types.h> 35 #include <sys/endian.h> 36 #include <sys/systm.h> 37 38 #include <lib/libkern/libkern.h> 39 40 #else /* !_KERNEL */ 41 42 #include <endian.h> 43 #include <stdint.h> 44 #include <stdio.h> 45 #include <string.h> 46 47 static void 48 hexdump(int (*prf)(const char *, ...) __printflike(1,2), const char *prefix, 49 const void *buf, size_t len) 50 { 51 const uint8_t *p = buf; 52 size_t i; 53 54 (*prf)("%s (%zu bytes)\n", prefix, len); 55 for (i = 0; i < len; i++) { 56 if (i % 16 == 8) 57 (*prf)(" "); 58 else 59 (*prf)(" "); 60 (*prf)("%02hhx", p[i]); 61 if ((i + 1) % 16 == 0) 62 (*prf)("\n"); 63 } 64 if (i % 16) 65 (*prf)("\n"); 66 } 67 68 #endif /* _KERNEL */ 69 70 #include <crypto/aes/aes.h> 71 #include <crypto/aes/aes_impl.h> 72 73 static const unsigned aes_keybytes[] __unused = { 16, 24, 32 }; 74 static const unsigned aes_keybits[] __unused = { 128, 192, 256 }; 75 static const unsigned aes_nrounds[] = { 10, 12, 14 }; 76 77 #define aes_selftest_fail(impl, actual, expected, nbytes, fmt, args...) \ 78 ({ \ 79 printf("%s "fmt": self-test failed\n", (impl)->ai_name, ##args); \ 80 hexdump(printf, "was", (actual), (nbytes)); \ 81 hexdump(printf, "expected", (expected), (nbytes)); \ 82 -1; \ 83 }) 84 85 static int 86 aes_selftest_encdec(const struct aes_impl *impl) 87 { 88 /* 89 * head -c 16 < /dev/zero | openssl enc -aes-{128,192,256}-ecb 90 * -nopad -K 000102030405060708090a0b0c0d... | hexdump -C 91 */ 92 static const uint8_t expected[3][16] = { 93 [0] = { 94 0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82, 95 0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79, 96 }, 97 [1] = { 98 0x91,0x62,0x51,0x82,0x1c,0x73,0xa5,0x22, 99 0xc3,0x96,0xd6,0x27,0x38,0x01,0x96,0x07, 100 }, 101 [2] = { 102 0xf2,0x90,0x00,0xb6,0x2a,0x49,0x9f,0xd0, 103 0xa9,0xf3,0x9a,0x6a,0xdd,0x2e,0x77,0x80, 104 }, 105 }; 106 struct aesenc enc; 107 struct aesdec dec; 108 uint8_t key[32]; 109 uint8_t in[16]; 110 uint8_t outbuf[18] = { [0] = 0x1a, [17] = 0x1a }, *out = outbuf + 1; 111 unsigned i; 112 113 for (i = 0; i < 32; i++) 114 key[i] = i; 115 for (i = 0; i < 16; i++) 116 in[i] = 0; 117 118 for (i = 0; i < 3; i++) { 119 impl->ai_setenckey(&enc, key, aes_nrounds[i]); 120 impl->ai_setdeckey(&dec, key, aes_nrounds[i]); 121 impl->ai_enc(&enc, in, out, aes_nrounds[i]); 122 if (memcmp(out, expected[i], 16)) 123 return aes_selftest_fail(impl, out, expected[i], 16, 124 "AES-%u enc", aes_keybits[i]); 125 impl->ai_dec(&dec, out, out, aes_nrounds[i]); 126 if (memcmp(out, in, 16)) 127 return aes_selftest_fail(impl, out, in, 16, 128 "AES-%u dec", aes_keybits[i]); 129 } 130 131 if (outbuf[0] != 0x1a) 132 return aes_selftest_fail(impl, outbuf, 133 (const uint8_t[1]){0x1a}, 1, 134 "AES overrun preceding"); 135 if (outbuf[17] != 0x1a) 136 return aes_selftest_fail(impl, outbuf + 17, 137 (const uint8_t[1]){0x1a}, 1, 138 "AES overrun following"); 139 140 /* Success! */ 141 return 0; 142 } 143 144 static int 145 aes_selftest_encdec_cbc(const struct aes_impl *impl) 146 { 147 static const uint8_t expected[3][144] = { 148 [0] = { 149 0xfe,0xf1,0xa8,0xb6,0x25,0xf0,0xc4,0x3a, 150 0x71,0x08,0xb6,0x23,0xa6,0xfb,0x90,0xca, 151 0x9e,0x64,0x6d,0x95,0xb5,0xf5,0x41,0x24, 152 0xd2,0xe6,0x60,0xda,0x6c,0x69,0xc4,0xa0, 153 0x4d,0xaa,0x94,0xf6,0x66,0x1e,0xaa,0x85, 154 0x68,0xc5,0x6b,0x2e,0x77,0x7a,0x68,0xff, 155 0x45,0x15,0x45,0xc5,0x9c,0xbb,0x3a,0x23, 156 0x08,0x3a,0x06,0xdd,0xc0,0x52,0xd2,0xb7, 157 0x47,0xaa,0x1c,0xc7,0xb5,0xa9,0x7d,0x04, 158 0x60,0x67,0x78,0xf6,0xb9,0xba,0x26,0x84, 159 0x45,0x72,0x44,0xed,0xa3,0xd3,0xa0,0x3f, 160 0x19,0xee,0x3f,0x94,0x59,0x52,0x4b,0x13, 161 0xfd,0x81,0xcc,0xf9,0xf2,0x29,0xd7,0xec, 162 0xde,0x03,0x56,0x01,0x4a,0x19,0x86,0xc0, 163 0x87,0xce,0xe1,0xcc,0x13,0xf1,0x2e,0xda, 164 0x3f,0xfe,0xa4,0x64,0xe7,0x48,0xb4,0x7b, 165 0x73,0x62,0x5a,0x80,0x5e,0x01,0x20,0xa5, 166 0x0a,0xd7,0x98,0xa7,0xd9,0x8b,0xff,0xc2, 167 }, 168 [1] = { 169 0xa6,0x87,0xf0,0x92,0x68,0xc8,0xd6,0x42, 170 0xa8,0x83,0x1c,0x92,0x65,0x8c,0xd9,0xfe, 171 0x0b,0x1a,0xc6,0x96,0x27,0x44,0xd4,0x14, 172 0xfc,0xe7,0x85,0xb2,0x71,0xc7,0x11,0x39, 173 0xed,0x36,0xd3,0x5c,0xa7,0xf7,0x3d,0xc9, 174 0xa2,0x54,0x8b,0xb4,0xfa,0xe8,0x21,0xf9, 175 0xfd,0x6a,0x42,0x85,0xde,0x66,0xd4,0xc0, 176 0xa7,0xd3,0x5b,0xe1,0xe6,0xac,0xea,0xf9, 177 0xa3,0x15,0x68,0xf4,0x66,0x4c,0x23,0x75, 178 0x58,0xba,0x7f,0xca,0xbf,0x40,0x56,0x79, 179 0x2f,0xbf,0xdf,0x5f,0x56,0xcb,0xa0,0xe4, 180 0x22,0x65,0x6a,0x8f,0x4f,0xff,0x11,0x6b, 181 0x57,0xeb,0x45,0xeb,0x9d,0x7f,0xfe,0x9c, 182 0x8b,0x30,0xa8,0xb0,0x7e,0x27,0xf8,0xbc, 183 0x1f,0xf8,0x15,0x34,0x36,0x4f,0x46,0x73, 184 0x81,0x90,0x4b,0x4b,0x46,0x4d,0x01,0x45, 185 0xa1,0xc3,0x0b,0xa8,0x5a,0xab,0xc1,0x88, 186 0x66,0xc8,0x1a,0x94,0x17,0x64,0x6f,0xf4, 187 }, 188 [2] = { 189 0x22,0x4c,0x27,0xf4,0xba,0x37,0x8b,0x27, 190 0xd3,0xd6,0x88,0x8a,0xdc,0xed,0x64,0x42, 191 0x19,0x60,0x31,0x09,0xf3,0x72,0xd2,0xc2, 192 0xd3,0xe3,0xff,0xce,0xc5,0x03,0x9f,0xce, 193 0x99,0x49,0x8a,0xf2,0xe1,0xba,0xe2,0xa8, 194 0xd7,0x32,0x07,0x2d,0xb0,0xb3,0xbc,0x67, 195 0x32,0x9a,0x3e,0x7d,0x16,0x23,0xe7,0x24, 196 0x84,0xe1,0x15,0x03,0x9c,0xa2,0x7a,0x95, 197 0x34,0xa8,0x04,0x4e,0x79,0x31,0x50,0x26, 198 0x76,0xd1,0x10,0xce,0xec,0x13,0xf7,0xfb, 199 0x94,0x6b,0x76,0x50,0x5f,0xb2,0x3e,0x7c, 200 0xbe,0x97,0xe7,0x13,0x06,0x9e,0x2d,0xc4, 201 0x46,0x65,0xa7,0x69,0x37,0x07,0x25,0x37, 202 0xe5,0x48,0x51,0xa8,0x58,0xe8,0x4d,0x7c, 203 0xb5,0xbe,0x25,0x13,0xbc,0x11,0xc2,0xde, 204 0xdb,0x00,0xef,0x1c,0x1d,0xeb,0xe3,0x49, 205 0x1c,0xc0,0x78,0x29,0x76,0xc0,0xde,0x3a, 206 0x0e,0x96,0x8f,0xea,0xd7,0x42,0x4e,0xb4, 207 }, 208 }; 209 struct aesenc enc; 210 struct aesdec dec; 211 uint8_t key[32]; 212 uint8_t in[144]; 213 uint8_t outbuf[146] = { [0] = 0x1a, [145] = 0x1a }, *out = outbuf + 1; 214 uint8_t iv0[16], iv[16]; 215 unsigned i, j; 216 217 for (i = 0; i < 32; i++) 218 key[i] = i; 219 for (i = 0; i < 16; i++) 220 iv0[i] = 0x20 ^ i; 221 for (i = 0; i < 144; i++) 222 in[i] = 0x80 ^ i; 223 224 for (i = 0; i < 3; i++) { 225 impl->ai_setenckey(&enc, key, aes_nrounds[i]); 226 impl->ai_setdeckey(&dec, key, aes_nrounds[i]); 227 228 /* Try one swell foop. */ 229 memcpy(iv, iv0, 16); 230 impl->ai_cbc_enc(&enc, in, out, 144, iv, aes_nrounds[i]); 231 if (memcmp(out, expected[i], 144)) 232 return aes_selftest_fail(impl, out, expected[i], 144, 233 "AES-%u-CBC enc", aes_keybits[i]); 234 235 memcpy(iv, iv0, 16); 236 impl->ai_cbc_dec(&dec, out, out, 144, iv, aes_nrounds[i]); 237 if (memcmp(out, in, 144)) 238 return aes_selftest_fail(impl, out, in, 144, 239 "AES-%u-CBC dec", aes_keybits[i]); 240 241 /* Try incrementally, with IV update. */ 242 for (j = 0; j < 144; j += 16) { 243 memcpy(iv, iv0, 16); 244 impl->ai_cbc_enc(&enc, in, out, j, iv, aes_nrounds[i]); 245 impl->ai_cbc_enc(&enc, in + j, out + j, 144 - j, iv, 246 aes_nrounds[i]); 247 if (memcmp(out, expected[i], 144)) 248 return aes_selftest_fail(impl, out, 249 expected[i], 144, "AES-%u-CBC enc inc %u", 250 aes_keybits[i], j); 251 252 memcpy(iv, iv0, 16); 253 impl->ai_cbc_dec(&dec, out, out, j, iv, 254 aes_nrounds[i]); 255 impl->ai_cbc_dec(&dec, out + j, out + j, 144 - j, iv, 256 aes_nrounds[i]); 257 if (memcmp(out, in, 144)) 258 return aes_selftest_fail(impl, out, 259 in, 144, "AES-%u-CBC dec inc %u", 260 aes_keybits[i], j); 261 } 262 } 263 264 if (outbuf[0] != 0x1a) 265 return aes_selftest_fail(impl, outbuf, 266 (const uint8_t[1]){0x1a}, 1, 267 "AES-CBC overrun preceding"); 268 if (outbuf[145] != 0x1a) 269 return aes_selftest_fail(impl, outbuf + 145, 270 (const uint8_t[1]){0x1a}, 1, 271 "AES-CBC overrun following"); 272 273 /* Success! */ 274 return 0; 275 } 276 277 static int 278 aes_selftest_encdec_xts(const struct aes_impl *impl) 279 { 280 uint64_t blkno[3] = { 0, 1, 0xff }; 281 static const uint8_t expected[3][144] = { 282 [0] = { 283 /* IEEE P1619-D16, XTS-AES-128, Vector 4, truncated */ 284 0x27,0xa7,0x47,0x9b,0xef,0xa1,0xd4,0x76, 285 0x48,0x9f,0x30,0x8c,0xd4,0xcf,0xa6,0xe2, 286 0xa9,0x6e,0x4b,0xbe,0x32,0x08,0xff,0x25, 287 0x28,0x7d,0xd3,0x81,0x96,0x16,0xe8,0x9c, 288 0xc7,0x8c,0xf7,0xf5,0xe5,0x43,0x44,0x5f, 289 0x83,0x33,0xd8,0xfa,0x7f,0x56,0x00,0x00, 290 0x05,0x27,0x9f,0xa5,0xd8,0xb5,0xe4,0xad, 291 0x40,0xe7,0x36,0xdd,0xb4,0xd3,0x54,0x12, 292 0x32,0x80,0x63,0xfd,0x2a,0xab,0x53,0xe5, 293 0xea,0x1e,0x0a,0x9f,0x33,0x25,0x00,0xa5, 294 0xdf,0x94,0x87,0xd0,0x7a,0x5c,0x92,0xcc, 295 0x51,0x2c,0x88,0x66,0xc7,0xe8,0x60,0xce, 296 0x93,0xfd,0xf1,0x66,0xa2,0x49,0x12,0xb4, 297 0x22,0x97,0x61,0x46,0xae,0x20,0xce,0x84, 298 0x6b,0xb7,0xdc,0x9b,0xa9,0x4a,0x76,0x7a, 299 0xae,0xf2,0x0c,0x0d,0x61,0xad,0x02,0x65, 300 0x5e,0xa9,0x2d,0xc4,0xc4,0xe4,0x1a,0x89, 301 0x52,0xc6,0x51,0xd3,0x31,0x74,0xbe,0x51, 302 }, 303 [1] = { 304 }, 305 [2] = { 306 /* IEEE P1619-D16, XTS-AES-256, Vector 10, truncated */ 307 0x1c,0x3b,0x3a,0x10,0x2f,0x77,0x03,0x86, 308 0xe4,0x83,0x6c,0x99,0xe3,0x70,0xcf,0x9b, 309 0xea,0x00,0x80,0x3f,0x5e,0x48,0x23,0x57, 310 0xa4,0xae,0x12,0xd4,0x14,0xa3,0xe6,0x3b, 311 0x5d,0x31,0xe2,0x76,0xf8,0xfe,0x4a,0x8d, 312 0x66,0xb3,0x17,0xf9,0xac,0x68,0x3f,0x44, 313 0x68,0x0a,0x86,0xac,0x35,0xad,0xfc,0x33, 314 0x45,0xbe,0xfe,0xcb,0x4b,0xb1,0x88,0xfd, 315 0x57,0x76,0x92,0x6c,0x49,0xa3,0x09,0x5e, 316 0xb1,0x08,0xfd,0x10,0x98,0xba,0xec,0x70, 317 0xaa,0xa6,0x69,0x99,0xa7,0x2a,0x82,0xf2, 318 0x7d,0x84,0x8b,0x21,0xd4,0xa7,0x41,0xb0, 319 0xc5,0xcd,0x4d,0x5f,0xff,0x9d,0xac,0x89, 320 0xae,0xba,0x12,0x29,0x61,0xd0,0x3a,0x75, 321 0x71,0x23,0xe9,0x87,0x0f,0x8a,0xcf,0x10, 322 0x00,0x02,0x08,0x87,0x89,0x14,0x29,0xca, 323 0x2a,0x3e,0x7a,0x7d,0x7d,0xf7,0xb1,0x03, 324 0x55,0x16,0x5c,0x8b,0x9a,0x6d,0x0a,0x7d, 325 }, 326 }; 327 static const uint8_t key1[32] = { 328 0x27,0x18,0x28,0x18,0x28,0x45,0x90,0x45, 329 0x23,0x53,0x60,0x28,0x74,0x71,0x35,0x26, 330 0x62,0x49,0x77,0x57,0x24,0x70,0x93,0x69, 331 0x99,0x59,0x57,0x49,0x66,0x96,0x76,0x27, 332 }; 333 static const uint8_t key2[32] = { 334 0x31,0x41,0x59,0x26,0x53,0x58,0x97,0x93, 335 0x23,0x84,0x62,0x64,0x33,0x83,0x27,0x95, 336 0x02,0x88,0x41,0x97,0x16,0x93,0x99,0x37, 337 0x51,0x05,0x82,0x09,0x74,0x94,0x45,0x92, 338 }; 339 struct aesenc enc; 340 struct aesdec dec; 341 uint8_t in[144]; 342 uint8_t outbuf[146] = { [0] = 0x1a, [145] = 0x1a }, *out = outbuf + 1; 343 uint8_t blkno_buf[16]; 344 uint8_t iv0[16], iv[16]; 345 unsigned i; 346 347 for (i = 0; i < 144; i++) 348 in[i] = i; 349 350 for (i = 0; i < 3; i++) { 351 if (i == 1) /* XXX missing AES-192 test vector */ 352 continue; 353 354 /* Format the data unit sequence number. */ 355 memset(blkno_buf, 0, sizeof blkno_buf); 356 le64enc(blkno_buf, blkno[i]); 357 358 /* Generate the tweak. */ 359 impl->ai_setenckey(&enc, key2, aes_nrounds[i]); 360 impl->ai_enc(&enc, blkno_buf, iv0, aes_nrounds[i]); 361 362 /* Load the data encryption key. */ 363 impl->ai_setenckey(&enc, key1, aes_nrounds[i]); 364 impl->ai_setdeckey(&dec, key1, aes_nrounds[i]); 365 366 /* Try one swell foop. */ 367 memcpy(iv, iv0, 16); 368 impl->ai_xts_enc(&enc, in, out, 144, iv, aes_nrounds[i]); 369 if (memcmp(out, expected[i], 144)) 370 return aes_selftest_fail(impl, out, expected[i], 144, 371 "AES-%u-XTS enc", aes_keybits[i]); 372 373 memcpy(iv, iv0, 16); 374 impl->ai_xts_dec(&dec, out, out, 144, iv, aes_nrounds[i]); 375 if (memcmp(out, in, 144)) 376 return aes_selftest_fail(impl, out, in, 144, 377 "AES-%u-XTS dec", aes_keybits[i]); 378 379 /* Try incrementally, with IV update. */ 380 memcpy(iv, iv0, 16); 381 impl->ai_xts_enc(&enc, in, out, 16, iv, aes_nrounds[i]); 382 impl->ai_xts_enc(&enc, in + 16, out + 16, 128, iv, 383 aes_nrounds[i]); 384 if (memcmp(out, expected[i], 144)) 385 return aes_selftest_fail(impl, out, expected[i], 144, 386 "AES-%u-XTS enc incremental", aes_keybits[i]); 387 388 memcpy(iv, iv0, 16); 389 impl->ai_xts_dec(&dec, out, out, 128, iv, aes_nrounds[i]); 390 impl->ai_xts_dec(&dec, out + 128, out + 128, 16, iv, 391 aes_nrounds[i]); 392 if (memcmp(out, in, 144)) 393 return aes_selftest_fail(impl, out, in, 144, 394 "AES-%u-XTS dec incremental", aes_keybits[i]); 395 } 396 397 if (outbuf[0] != 0x1a) 398 return aes_selftest_fail(impl, outbuf, 399 (const uint8_t[1]){0x1a}, 1, 400 "AES-XTS overrun preceding"); 401 if (outbuf[145] != 0x1a) 402 return aes_selftest_fail(impl, outbuf + 145, 403 (const uint8_t[1]){0x1a}, 1, 404 "AES-XTS overrun following"); 405 406 /* Success! */ 407 return 0; 408 } 409 410 static int 411 aes_selftest_cbcmac(const struct aes_impl *impl) 412 { 413 static const uint8_t m[48] = { 414 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 415 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 416 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 417 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, 418 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, 419 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f, 420 }; 421 static uint8_t auth16[16] = { 422 0x7a,0xca,0x0f,0xd9, 0xbc,0xd6,0xec,0x7c, 423 0x9f,0x97,0x46,0x66, 0x16,0xe6,0xa2,0x82, 424 }; 425 static uint8_t auth48[16] = { 426 0x26,0x9a,0xe5,0xfc, 0x8c,0x53,0x0f,0xf7, 427 0x6b,0xd9,0xec,0x05, 0x40,0xf7,0x35,0x13, 428 }; 429 static const uint8_t key[16]; 430 struct aesenc enc; 431 uint8_t auth[16]; 432 const unsigned nr = AES_128_NROUNDS; 433 434 memset(auth, 0, sizeof auth); 435 436 impl->ai_setenckey(&enc, key, nr); 437 impl->ai_cbcmac_update1(&enc, m, 16, auth, nr); 438 if (memcmp(auth, auth16, 16)) 439 return aes_selftest_fail(impl, auth, auth16, 16, 440 "AES-128 CBC-MAC (16)"); 441 impl->ai_cbcmac_update1(&enc, m + 16, 32, auth, nr); 442 if (memcmp(auth, auth48, 16)) 443 return aes_selftest_fail(impl, auth, auth48, 16, 444 "AES-128 CBC-MAC (48)"); 445 446 return 0; 447 } 448 449 static int 450 aes_selftest_ccm(const struct aes_impl *impl) 451 { 452 static const uint8_t ptxt[48] = { 453 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07, 454 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f, 455 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17, 456 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f, 457 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27, 458 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f, 459 }; 460 static uint8_t ctr0[16] = { 461 /* L - 1, #octets in counter */ 462 [0] = 0x01, 463 /* nonce */ 464 [1] = 0,1,2,3,4,5,6,7,8,9,10,11,12, 465 [14] = 0, 466 [15] = 254, 467 }; 468 static uint8_t authctr16[32] = { 469 /* authentication tag */ 470 0x7a,0xca,0x0f,0xd9, 0xbc,0xd6,0xec,0x7c, 471 0x9f,0x97,0x46,0x66, 0x16,0xe6,0xa2,0x82, 472 473 /* L - 1, #octets in counter */ 474 [16 + 0] = 0x01, 475 /* nonce */ 476 [16 + 1] = 0,1,2,3,4,5,6,7,8,9,10,11,12, 477 [16 + 14] = 0, 478 [16 + 15] = 255, 479 }; 480 static uint8_t authctr48[32] = { 481 /* authentication tag */ 482 0x26,0x9a,0xe5,0xfc, 0x8c,0x53,0x0f,0xf7, 483 0x6b,0xd9,0xec,0x05, 0x40,0xf7,0x35,0x13, 484 485 /* L - 1, #octets in counter */ 486 [16 + 0] = 0x01, 487 /* nonce */ 488 [16 + 1] = 0,1,2,3,4,5,6,7,8,9,10,11,12, 489 [16 + 14] = 1, 490 [16 + 15] = 1, 491 }; 492 static uint8_t ctxt[48] = { 493 0xa4,0x35,0x07,0x5c, 0xdf,0x2d,0x67,0xd3, 494 0xbf,0x1f,0x36,0x93, 0xe4,0x43,0xcb,0x1e, 495 0xa0,0x82,0x9c,0x2a, 0x0b,0x66,0x46,0x05, 496 0x80,0x17,0x71,0xa1, 0x7b,0x09,0xa7,0xd5, 497 0x91,0x0b,0xb3,0x96, 0xd1,0x5e,0x29,0x3e, 498 0x74,0x94,0x74,0x6d, 0x6b,0x25,0x43,0x8c, 499 }; 500 static const uint8_t key[16]; 501 struct aesenc enc; 502 uint8_t authctr[32]; 503 uint8_t buf[48]; 504 const unsigned nr = AES_128_NROUNDS; 505 int result = 0; 506 507 impl->ai_setenckey(&enc, key, nr); 508 509 memset(authctr, 0, 16); 510 memcpy(authctr + 16, ctr0, 16); 511 512 impl->ai_ccm_enc1(&enc, ptxt, buf, 16, authctr, nr); 513 if (memcmp(authctr, authctr16, 32)) 514 result |= aes_selftest_fail(impl, authctr, authctr16, 32, 515 "AES-128 CCM encrypt auth/ctr (16)"); 516 impl->ai_ccm_enc1(&enc, ptxt + 16, buf + 16, 32, authctr, nr); 517 if (memcmp(authctr, authctr48, 32)) 518 result |= aes_selftest_fail(impl, authctr, authctr48, 32, 519 "AES-128 CCM encrypt auth/ctr (48)"); 520 521 if (memcmp(buf, ctxt, 32)) 522 result |= aes_selftest_fail(impl, buf, ctxt, 48, 523 "AES-128 CCM ciphertext"); 524 525 memset(authctr, 0, 16); 526 memcpy(authctr + 16, ctr0, 16); 527 528 impl->ai_ccm_dec1(&enc, ctxt, buf, 16, authctr, nr); 529 if (memcmp(authctr, authctr16, 32)) 530 result |= aes_selftest_fail(impl, authctr, authctr16, 32, 531 "AES-128 CCM decrypt auth/ctr (16)"); 532 impl->ai_ccm_dec1(&enc, ctxt + 16, buf + 16, 32, authctr, nr); 533 if (memcmp(authctr, authctr48, 32)) 534 result |= aes_selftest_fail(impl, authctr, authctr48, 32, 535 "AES-128 CCM decrypt auth/ctr (48)"); 536 537 if (memcmp(buf, ptxt, 32)) 538 result |= aes_selftest_fail(impl, buf, ptxt, 48, 539 "AES-128 CCM plaintext"); 540 541 return result; 542 } 543 544 int 545 aes_selftest(const struct aes_impl *impl) 546 { 547 int result = 0; 548 549 if (impl->ai_probe()) 550 return -1; 551 552 if (aes_selftest_encdec(impl)) 553 result = -1; 554 if (aes_selftest_encdec_cbc(impl)) 555 result = -1; 556 if (aes_selftest_encdec_xts(impl)) 557 result = -1; 558 if (aes_selftest_cbcmac(impl)) 559 result = -1; 560 if (aes_selftest_ccm(impl)) 561 result = -1; 562 563 return result; 564 } 565