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