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