blob: ae883b247d6f4efec22d0accc8ca0aaf683a2c28 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
9 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010010 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
12 */
13
Gilles Peskinedb09ef62020-06-03 01:43:33 +020014#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000017
Rich Evans00ab4702015-02-06 13:43:58 +000018#include <string.h>
19
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000020#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030021#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050022#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000023#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080024
Dave Rodgman782df0352023-09-29 12:57:52 +010025#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Dave Rodgman9fd1b522023-10-10 15:23:44 +010026#if !((defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_AESCE_C)) || \
27 (defined(MBEDTLS_ARCH_IS_X64) && defined(MBEDTLS_AESNI_C)) || \
28 (defined(MBEDTLS_ARCH_IS_X86) && defined(MBEDTLS_AESNI_C)))
Jerry Yu69436812023-04-25 11:08:30 +080029#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080030#endif
31#endif
32
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000034#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010035#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080036#if defined(MBEDTLS_AESCE_C)
37#include "aesce.h"
38#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/platform.h"
Dave Rodgman591ff052024-01-13 16:42:38 +000041#include "ctr.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010042
Yanray Wangf03b4912023-11-09 11:23:17 +080043/*
44 * This is a convenience shorthand macro to check if we need reverse S-box and
45 * reverse tables. It's private and only defined in this file.
46 */
47#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \
48 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \
Yanray Wangb67b4742023-10-31 17:10:32 +080049 !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wangdbcc0c62023-08-30 15:04:01 +080050#define MBEDTLS_AES_NEED_REVERSE_TABLES
51#endif
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000056/*
57 * Forward S-box
58 */
Dave Rodgman18ddf612023-10-04 14:03:12 +010059MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +000060{
61 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
62 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
63 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
64 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
65 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
66 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
67 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
68 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
69 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
70 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
71 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
72 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
73 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
74 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
75 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
76 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
77 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
78 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
79 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
80 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
81 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
82 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
83 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
84 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
85 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
86 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
87 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
88 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
89 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
90 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
91 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
92 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
93};
94
95/*
96 * Forward tables
97 */
98#define FT \
99\
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
101 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
102 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
103 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
104 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
105 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
106 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
107 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
108 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
109 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
110 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
111 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
112 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
113 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
114 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
115 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
116 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
117 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
118 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
119 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
120 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
121 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
122 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
123 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
124 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
125 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
126 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
127 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
128 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
129 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
130 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
131 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
132 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
133 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
134 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
135 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
136 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
137 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
138 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
139 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
140 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
141 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
142 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
143 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
144 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
145 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
146 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
147 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
148 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
149 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
150 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
151 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
152 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
153 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
154 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
155 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
156 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
157 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
158 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
159 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
160 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
161 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
162 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
163 V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100166MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000167#undef V
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100170MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000171#undef V
172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100174MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000175#undef V
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100178MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000179#undef V
180
181#undef FT
182
183/*
184 * Reverse S-box
185 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100186MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000187{
188 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
189 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
190 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
191 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
192 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
193 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
194 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
195 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
196 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
197 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
198 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
199 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
200 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
201 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
202 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
203 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
204 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
205 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
206 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
207 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
208 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
209 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
210 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
211 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
212 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
213 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
214 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
215 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
216 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
217 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
218 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
219 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
220};
221
222/*
223 * Reverse tables
224 */
225#define RT \
226\
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
228 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
229 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
230 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
231 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
232 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
233 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
234 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
235 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
236 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
237 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
238 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
239 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
240 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
241 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
242 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
243 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
244 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
245 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
246 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
247 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
248 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
249 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
250 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
251 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
252 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
253 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
254 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
255 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
256 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
257 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
258 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
259 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
260 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
261 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
262 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
263 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
264 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
265 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
266 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
267 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
268 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
269 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
270 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
271 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
272 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
273 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
274 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
275 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
276 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
277 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
278 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
279 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
280 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
281 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
282 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
283 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
284 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
285 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
286 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
287 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
288 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
289 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
290 V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000291
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100294MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000295#undef V
296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100298MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000299#undef V
300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100302MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000303#undef V
304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100306MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000307#undef V
308
309#undef RT
310
311/*
312 * Round constants
313 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100314MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000315{
316 0x00000001, 0x00000002, 0x00000004, 0x00000008,
317 0x00000010, 0x00000020, 0x00000040, 0x00000080,
318 0x0000001B, 0x00000036
319};
320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000322
323/*
324 * Forward S-box & tables
325 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100326MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
327MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
328MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
329MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
330MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000331
332/*
333 * Reverse S-box & tables
334 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100335MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100336
Dave Rodgman18ddf612023-10-04 14:03:12 +0100337MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
338MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
339MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
340MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342/*
343 * Round constants
344 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100345MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347/*
348 * Tables generation code
349 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100350#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
351#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
352#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
Dave Rodgman18ddf612023-10-04 14:03:12 +0100354MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000355
Dave Rodgman18ddf612023-10-04 14:03:12 +0100356MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000357{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800358 int i;
359 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800360 uint8_t pow[256];
361 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
363 /*
364 * compute pow and log tables over GF(2^8)
365 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000367 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800368 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800369 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000370 }
371
372 /*
373 * calculate the round constants
374 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200376 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800377 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 }
379
380 /*
381 * generate the forward and reverse S-boxes
382 */
383 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800384#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000385 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800386#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000389 x = pow[255 - log[i]];
390
Yanray Wangfe944ce2023-06-26 18:16:01 +0800391 y = x; y = (y << 1) | (y >> 7);
392 x ^= y; y = (y << 1) | (y >> 7);
393 x ^= y; y = (y << 1) | (y >> 7);
394 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 x ^= y ^ 0x63;
396
Yanray Wangfe944ce2023-06-26 18:16:01 +0800397 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800398#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800400#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 }
402
403 /*
404 * generate the forward and reverse tables
405 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000407 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800408 y = XTIME(x);
409 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 FT0[i] = ((uint32_t) y) ^
412 ((uint32_t) x << 8) ^
413 ((uint32_t) x << 16) ^
414 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Hanno Beckerad049a92017-06-19 16:31:54 +0100416#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 FT1[i] = ROTL8(FT0[i]);
418 FT2[i] = ROTL8(FT1[i]);
419 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100420#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800422#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 x = RSb[i];
424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
426 ((uint32_t) MUL(0x09, x) << 8) ^
427 ((uint32_t) MUL(0x0D, x) << 16) ^
428 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Hanno Beckerad049a92017-06-19 16:31:54 +0100430#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 RT1[i] = ROTL8(RT0[i]);
432 RT2[i] = ROTL8(RT1[i]);
433 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100434#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800435#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 }
437}
438
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200439#undef ROTL8
440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Hanno Beckerad049a92017-06-19 16:31:54 +0100443#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
446#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
447#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200448
449#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100450#define AES_RT1(idx) ROTL8(RT0[idx])
451#define AES_RT2(idx) ROTL16(RT0[idx])
452#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200453
454#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100455#define AES_FT1(idx) ROTL8(FT0[idx])
456#define AES_FT2(idx) ROTL16(FT0[idx])
457#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200458
Hanno Becker177d3cf2017-06-07 15:52:48 +0100459#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200460
461#define AES_RT0(idx) RT0[idx]
462#define AES_RT1(idx) RT1[idx]
463#define AES_RT2(idx) RT2[idx]
464#define AES_RT3(idx) RT3[idx]
465
466#define AES_FT0(idx) FT0[idx]
467#define AES_FT1(idx) FT1[idx]
468#define AES_FT2(idx) FT2[idx]
469#define AES_FT3(idx) FT3[idx]
470
Hanno Becker177d3cf2017-06-07 15:52:48 +0100471#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200474{
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200476}
477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200479{
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200481 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200485}
486
Jaeden Amero9366feb2018-05-29 18:55:17 +0100487#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100488void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100489{
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_aes_init(&ctx->crypt);
491 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100492}
493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100495{
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100497 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 }
Simon Butcher5201e412018-12-06 17:40:14 +0000499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 mbedtls_aes_free(&ctx->crypt);
501 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100502}
503#endif /* MBEDTLS_CIPHER_MODE_XTS */
504
Gilles Peskine0de8f852023-03-16 17:14:59 +0100505/* Some implementations need the round keys to be aligned.
506 * Return an offset to be added to buf, such that (buf + offset) is
507 * correctly aligned.
508 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
509 * i.e. an offset of 1 means 4 bytes and so on.
510 */
Thomas Daubney62af02c2024-06-14 10:37:13 +0100511#if (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100512#define MAY_NEED_TO_ALIGN
513#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100514
Dave Rodgman18ddf612023-10-04 14:03:12 +0100515MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100516{
517#if defined(MAY_NEED_TO_ALIGN)
518 int align_16_bytes = 0;
519
Gilles Peskine9c682e72023-03-16 17:21:33 +0100520#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100521 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
522 align_16_bytes = 1;
523 }
524#endif
525
526 if (align_16_bytes) {
527 /* These implementations needs 16-byte alignment
528 * for the round key array. */
529 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
530 if (delta == 0) {
531 return 0;
532 } else {
533 return 4 - delta; // 16 bytes = 4 uint32_t
534 }
535 }
536#else /* MAY_NEED_TO_ALIGN */
537 (void) buf;
538#endif /* MAY_NEED_TO_ALIGN */
539
540 return 0;
541}
542
Paul Bakker5121ce52009-01-03 21:22:43 +0000543/*
544 * AES key schedule (encryption)
545 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200546#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100547int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
548 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000549{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000550 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000553 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800554#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000555 case 192: ctx->nr = 12; break;
556 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800557#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000559 }
560
Simon Butcher5201e412018-12-06 17:40:14 +0000561#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000563 aes_gen_tables();
564 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000565 }
566#endif
567
Gilles Peskine0de8f852023-03-16 17:14:59 +0100568 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100569 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100571#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
573 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
574 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100575#endif
576
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800577#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100578 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800579 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
580 }
581#endif
582
Jerry Yu29c91ba2023-08-04 11:02:04 +0800583#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800584 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000586 }
587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 case 10:
590
Jerry Yu3a0f0442023-08-17 17:06:21 +0800591 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200592 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
594 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
595 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
596 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 RK[5] = RK[1] ^ RK[4];
599 RK[6] = RK[2] ^ RK[5];
600 RK[7] = RK[3] ^ RK[6];
601 }
602 break;
603
Arto Kinnunen732ca322023-04-14 14:26:10 +0800604#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000605 case 12:
606
Jerry Yu3a0f0442023-08-17 17:06:21 +0800607 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200608 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
610 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
611 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
612 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614 RK[7] = RK[1] ^ RK[6];
615 RK[8] = RK[2] ^ RK[7];
616 RK[9] = RK[3] ^ RK[8];
617 RK[10] = RK[4] ^ RK[9];
618 RK[11] = RK[5] ^ RK[10];
619 }
620 break;
621
622 case 14:
623
Jerry Yu3a0f0442023-08-17 17:06:21 +0800624 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200625 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
627 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
628 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
629 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
631 RK[9] = RK[1] ^ RK[8];
632 RK[10] = RK[2] ^ RK[9];
633 RK[11] = RK[3] ^ RK[10];
634
635 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
637 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
638 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
639 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
641 RK[13] = RK[5] ^ RK[12];
642 RK[14] = RK[6] ^ RK[13];
643 RK[15] = RK[7] ^ RK[14];
644 }
645 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800646#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000647 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800650#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000651}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200652#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000653
654/*
655 * AES key schedule (decryption)
656 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800657#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100658int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
659 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000660{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800661#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800662 uint32_t *SK;
663#endif
664 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000666 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800667
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
Gilles Peskine0de8f852023-03-16 17:14:59 +0100671 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100672 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200674 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200676 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000678
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200679 ctx->nr = cty.nr;
680
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100681#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
683 mbedtls_aesni_inverse_key((unsigned char *) RK,
684 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200685 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100686 }
687#endif
688
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800689#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100690 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800691 mbedtls_aesce_inverse_key(
692 (unsigned char *) RK,
693 (const unsigned char *) (cty.buf + cty.rk_offset),
694 ctx->nr);
695 goto exit;
696 }
697#endif
698
Jerry Yu29c91ba2023-08-04 11:02:04 +0800699#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100700 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000701
702 *RK++ = *SK++;
703 *RK++ = *SK++;
704 *RK++ = *SK++;
705 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800706 SK -= 8;
707 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
708 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
710 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
711 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
712 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000713 }
714 }
715
716 *RK++ = *SK++;
717 *RK++ = *SK++;
718 *RK++ = *SK++;
719 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800720#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200721exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000725}
Yanray Wangb67b4742023-10-31 17:10:32 +0800726#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100727
728#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100729static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
730 unsigned int keybits,
731 const unsigned char **key1,
732 unsigned int *key1bits,
733 const unsigned char **key2,
734 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100735{
736 const unsigned int half_keybits = keybits / 2;
737 const unsigned int half_keybytes = half_keybits / 8;
738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100740 case 256: break;
741 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100743 }
744
745 *key1bits = half_keybits;
746 *key2bits = half_keybits;
747 *key1 = &key[0];
748 *key2 = &key[half_keybytes];
749
750 return 0;
751}
752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
754 const unsigned char *key,
755 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100756{
Janos Follath24eed8d2019-11-22 13:21:35 +0000757 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100758 const unsigned char *key1, *key2;
759 unsigned int key1bits, key2bits;
760
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
762 &key2, &key2bits);
763 if (ret != 0) {
764 return ret;
765 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100766
767 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
769 if (ret != 0) {
770 return ret;
771 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100772
773 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100775}
776
Gilles Peskine449bd832023-01-11 14:50:10 +0100777int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
778 const unsigned char *key,
779 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100780{
Janos Follath24eed8d2019-11-22 13:21:35 +0000781 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100782 const unsigned char *key1, *key2;
783 unsigned int key1bits, key2bits;
784
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
786 &key2, &key2bits);
787 if (ret != 0) {
788 return ret;
789 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100790
791 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
793 if (ret != 0) {
794 return ret;
795 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100796
797 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100799}
800#endif /* MBEDTLS_CIPHER_MODE_XTS */
801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100803 do \
804 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
806 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
807 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
808 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100809 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
811 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
812 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
813 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100814 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
816 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
817 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
818 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100819 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
821 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
822 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
823 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
824 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100827 do \
828 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
830 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
831 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
832 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100833 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
835 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
836 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
837 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100838 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
840 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
841 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
842 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100843 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
845 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
846 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
847 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
848 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
850/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200851 * AES-ECB block encryption
852 */
853#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100854int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
855 const unsigned char input[16],
856 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200857{
858 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100859 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200861 uint32_t X[4];
862 uint32_t Y[4];
863 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200864
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
866 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
867 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
868 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
871 AES_FROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]);
872 AES_FROUND(t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3]);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200873 }
874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 AES_FROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200876
Gilles Peskine5197c662020-08-26 17:03:24 +0200877 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
879 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
880 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
881 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200882
Gilles Peskine5197c662020-08-26 17:03:24 +0200883 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
885 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
886 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
887 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200888
Gilles Peskine5197c662020-08-26 17:03:24 +0200889 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
891 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
892 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
893 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200894
Gilles Peskine5197c662020-08-26 17:03:24 +0200895 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
897 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
898 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
899 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
902 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
903 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
904 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200909}
910#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
911
912/*
913 * AES-ECB block decryption
914 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800915#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100916int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
917 const unsigned char input[16],
918 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200919{
920 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100921 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200923 uint32_t X[4];
924 uint32_t Y[4];
925 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
928 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
929 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
930 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
933 AES_RROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]);
934 AES_RROUND(t.X[0], t.X[1], t.X[2], t.X[3], t.Y[0], t.Y[1], t.Y[2], t.Y[3]);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935 }
936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 AES_RROUND(t.Y[0], t.Y[1], t.Y[2], t.Y[3], t.X[0], t.X[1], t.X[2], t.X[3]);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200938
Gilles Peskine5197c662020-08-26 17:03:24 +0200939 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
941 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
942 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
943 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200944
Gilles Peskine5197c662020-08-26 17:03:24 +0200945 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
947 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
948 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
949 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200950
Gilles Peskine5197c662020-08-26 17:03:24 +0200951 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
953 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
954 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
955 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200956
Gilles Peskine5197c662020-08-26 17:03:24 +0200957 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
959 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
960 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
961 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
964 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
965 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
966 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200971}
Yanray Wangb67b4742023-10-31 17:10:32 +0800972#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Thomas Daubney62af02c2024-06-14 10:37:13 +0100974/*
Thomas Daubney4e5d1832024-06-25 15:21:48 +0100975 * Our intrinsics-based implementation of AESNI requires the round keys to be
Thomas Daubney62af02c2024-06-14 10:37:13 +0100976 * aligned on a 16-byte boundary. We take care of this before creating them,
977 * but the AES context may have moved (this can happen if the library is
978 * called from a language with managed memory), and in later calls it might
979 * have a different alignment with respect to 16-byte memory. So we may need
980 * to realign.
Gilles Peskine148cad12023-03-16 13:08:42 +0100981 */
Thomas Daubney1d08e2f2024-06-25 09:18:20 +0100982#if defined(MAY_NEED_TO_ALIGN)
Dave Rodgman18ddf612023-10-04 14:03:12 +0100983MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +0100984{
Gilles Peskine0de8f852023-03-16 17:14:59 +0100985 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
986 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +0100987 memmove(ctx->buf + new_offset, // new address
988 ctx->buf + ctx->rk_offset, // current address
989 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
990 ctx->rk_offset = new_offset;
991 }
992}
Thomas Daubney1d08e2f2024-06-25 09:18:20 +0100993#endif /* MAY_NEED_TO_ALIGN */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200994/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000995 * AES-ECB block encryption/decryption
996 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100997int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
998 int mode,
999 const unsigned char input[16],
1000 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001001{
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001003 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001005
Gilles Peskine0de8f852023-03-16 17:14:59 +01001006#if defined(MAY_NEED_TO_ALIGN)
1007 aes_maybe_realign(ctx);
1008#endif
1009
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001010#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1012 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1013 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001014#endif
1015
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001016#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001017 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001018 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1019 }
1020#endif
1021
Jerry Yu29c91ba2023-08-04 11:02:04 +08001022#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001023#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang111159b2023-11-10 13:41:12 +08001024 if (mode == MBEDTLS_AES_DECRYPT) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang111159b2023-11-10 13:41:12 +08001026 } else
Jerry Yu29c91ba2023-08-04 11:02:04 +08001027#endif
Yanray Wang111159b2023-11-10 13:41:12 +08001028 {
1029 return mbedtls_internal_aes_encrypt(ctx, input, output);
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001030 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001031#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001032}
1033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001035
Paul Bakker5121ce52009-01-03 21:22:43 +00001036/*
1037 * AES-CBC buffer encryption/decryption
1038 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001039int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1040 int mode,
1041 size_t length,
1042 unsigned char iv[16],
1043 const unsigned char *input,
1044 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001045{
Gilles Peskine7820a572021-07-07 21:08:28 +02001046 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001047 unsigned char temp[16];
1048
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001050 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001052
Paul Elliott2ad93672023-08-11 11:07:06 +01001053 /* Nothing to do if length is zero. */
1054 if (length == 0) {
1055 return 0;
1056 }
1057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 if (length % 16) {
1059 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1060 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001061
Dave Rodgman906c63c2023-06-14 17:53:51 +01001062 const unsigned char *ivp = iv;
1063
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 if (mode == MBEDTLS_AES_DECRYPT) {
1065 while (length > 0) {
1066 memcpy(temp, input, 16);
1067 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1068 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001069 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001071 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001072 * the result for the next block in CBC, and the cost of transferring that data from
1073 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001074 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001075
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001077
1078 input += 16;
1079 output += 16;
1080 length -= 16;
1081 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 } else {
1083 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001084 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1087 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001088 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001090 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001091
1092 input += 16;
1093 output += 16;
1094 length -= 16;
1095 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001096 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001097 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001098 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001099
Gilles Peskine7820a572021-07-07 21:08:28 +02001100exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001102}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001104
Aorimn5f778012016-06-09 23:22:58 +02001105#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001106
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001107typedef unsigned char mbedtls_be128[16];
1108
1109/*
1110 * GF(2^128) multiplication function
1111 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001112 * This function multiplies a field element by x in the polynomial field
1113 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001114 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001115 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001116 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001117#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001118MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001119#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001120static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001121 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001122{
1123 uint64_t a, b, ra, rb;
1124
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 a = MBEDTLS_GET_UINT64_LE(x, 0);
1126 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001127
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1129 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1132 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001133}
1134
Aorimn5f778012016-06-09 23:22:58 +02001135/*
1136 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001137 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001138 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001139 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001140 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001141#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001142MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001143#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001144int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1145 int mode,
1146 size_t length,
1147 const unsigned char data_unit[16],
1148 const unsigned char *input,
1149 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001150{
Janos Follath24eed8d2019-11-22 13:21:35 +00001151 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001152 size_t blocks = length / 16;
1153 size_t leftover = length % 16;
1154 unsigned char tweak[16];
1155 unsigned char prev_tweak[16];
1156 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001157
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001159 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001161
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001162 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001164 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 }
Aorimn5f778012016-06-09 23:22:58 +02001166
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001167 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001169 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 }
Aorimn5f778012016-06-09 23:22:58 +02001171
Jaeden Amerod82cd862018-04-28 15:02:45 +01001172 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1174 data_unit, tweak);
1175 if (ret != 0) {
1176 return ret;
1177 }
Aorimn5f778012016-06-09 23:22:58 +02001178
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001180 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001181 /* We are on the last block in a decrypt operation that has
1182 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001183 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001184 * the leftovers and then update the current tweak for use on this,
1185 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 memcpy(prev_tweak, tweak, sizeof(tweak));
1187 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001188 }
1189
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001191
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1193 if (ret != 0) {
1194 return ret;
1195 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001196
Gilles Peskine449bd832023-01-11 14:50:10 +01001197 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001198
1199 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001200 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001201
1202 output += 16;
1203 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001204 }
1205
Gilles Peskine449bd832023-01-11 14:50:10 +01001206 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001207 /* If we are on the leftover bytes in a decrypt operation, we need to
1208 * use the previous tweak for these bytes (as saved in prev_tweak). */
1209 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001210
Jaeden Amerod82cd862018-04-28 15:02:45 +01001211 /* We are now on the final part of the data unit, which doesn't divide
1212 * evenly by 16. It's time for ciphertext stealing. */
1213 size_t i;
1214 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001215
Jaeden Amerod82cd862018-04-28 15:02:45 +01001216 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001217 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001219 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001220 }
Aorimn5f778012016-06-09 23:22:58 +02001221
Dave Rodgman069e7f42022-11-24 19:37:26 +00001222 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001224
Jaeden Amerod82cd862018-04-28 15:02:45 +01001225 /* Copy ciphertext bytes from the previous block for input in this
1226 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001228
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1230 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001231 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001232 }
Aorimn5f778012016-06-09 23:22:58 +02001233
Jaeden Amerod82cd862018-04-28 15:02:45 +01001234 /* Write the result back to the previous block, overriding the previous
1235 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001236 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001237 }
1238
Gilles Peskine449bd832023-01-11 14:50:10 +01001239 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001240}
1241#endif /* MBEDTLS_CIPHER_MODE_XTS */
1242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001243#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001244/*
1245 * AES-CFB128 buffer encryption/decryption
1246 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001247int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1248 int mode,
1249 size_t length,
1250 size_t *iv_off,
1251 unsigned char iv[16],
1252 const unsigned char *input,
1253 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001254{
Paul Bakker27fdf462011-06-09 13:55:13 +00001255 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001256 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001257 size_t n;
1258
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001260 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001262
1263 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001264
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 if (n > 15) {
1266 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1267 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001268
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 if (mode == MBEDTLS_AES_DECRYPT) {
1270 while (length--) {
1271 if (n == 0) {
1272 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1273 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001274 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001276 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001277
1278 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001280 iv[n] = (unsigned char) c;
1281
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001283 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 } else {
1285 while (length--) {
1286 if (n == 0) {
1287 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1288 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001289 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001291 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001292
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001296 }
1297 }
1298
1299 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001300 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001301
Gilles Peskine7820a572021-07-07 21:08:28 +02001302exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001303 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001304}
Paul Bakker556efba2014-01-24 15:38:12 +01001305
1306/*
1307 * AES-CFB8 buffer encryption/decryption
1308 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001309int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1310 int mode,
1311 size_t length,
1312 unsigned char iv[16],
1313 const unsigned char *input,
1314 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001315{
Gilles Peskine7820a572021-07-07 21:08:28 +02001316 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001317 unsigned char c;
1318 unsigned char ov[17];
1319
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001321 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 }
1323 while (length--) {
1324 memcpy(ov, iv, 16);
1325 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1326 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001327 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 }
Paul Bakker556efba2014-01-24 15:38:12 +01001329
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001331 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 }
Paul Bakker556efba2014-01-24 15:38:12 +01001333
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001335
Gilles Peskine449bd832023-01-11 14:50:10 +01001336 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001337 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 }
Paul Bakker556efba2014-01-24 15:38:12 +01001339
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001341 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001342 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001343
Gilles Peskine7820a572021-07-07 21:08:28 +02001344exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001346}
Simon Butcher76a5b222018-04-22 22:57:27 +01001347#endif /* MBEDTLS_CIPHER_MODE_CFB */
1348
1349#if defined(MBEDTLS_CIPHER_MODE_OFB)
1350/*
1351 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1352 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001353int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1354 size_t length,
1355 size_t *iv_off,
1356 unsigned char iv[16],
1357 const unsigned char *input,
1358 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001359{
Simon Butcherad4e4932018-04-29 00:43:47 +01001360 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001361 size_t n;
1362
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001363 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001364
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 if (n > 15) {
1366 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1367 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001368
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 while (length--) {
1370 if (n == 0) {
1371 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1372 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001373 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001375 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001376 *output++ = *input++ ^ iv[n];
1377
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001379 }
1380
1381 *iv_off = n;
1382
Simon Butcherad4e4932018-04-29 00:43:47 +01001383exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001385}
1386#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001387
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001389/*
1390 * AES-CTR buffer encryption/decryption
1391 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001392int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1393 size_t length,
1394 size_t *nc_off,
1395 unsigned char nonce_counter[16],
1396 unsigned char stream_block[16],
1397 const unsigned char *input,
1398 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001399{
Gilles Peskine7820a572021-07-07 21:08:28 +02001400 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001401
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001402 size_t offset = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001403
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001404 if (offset > 0x0F) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001405 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1406 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001407
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001408 for (size_t i = 0; i < length;) {
1409 size_t n = 16;
1410 if (offset == 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001411 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1412 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001413 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 }
Dave Rodgman591ff052024-01-13 16:42:38 +00001415 mbedtls_ctr_increment_counter(nonce_counter);
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001416 } else {
1417 n -= offset;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001418 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001419
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001420 if (n > (length - i)) {
1421 n = (length - i);
1422 }
1423 mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
1424 // offset might be non-zero for the last block, but in that case, we don't use it again
1425 offset = 0;
1426 i += n;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001427 }
1428
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001429 // capture offset for future resumption
1430 *nc_off = (*nc_off + length) % 16;
1431
Gilles Peskine7820a572021-07-07 21:08:28 +02001432 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001433
Gilles Peskine7820a572021-07-07 21:08:28 +02001434exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001435 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001436}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001437#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001439#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001441#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001442/*
1443 * AES test vectors from:
1444 *
1445 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1446 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001447#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001448static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001449{
1450 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1451 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001452#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001453 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1454 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1455 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1456 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001457#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001458};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001459#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001460
Yanray Wang62c99912023-05-11 11:06:53 +08001461static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001462{
1463 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1464 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001465#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001466 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1467 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1468 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1469 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001470#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001471};
1472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001473#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001474static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001475{
1476 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1477 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001478#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001479 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1480 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1481 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1482 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001483#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001484};
1485
Yanray Wang62c99912023-05-11 11:06:53 +08001486static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001487{
1488 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1489 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001490#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001491 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1492 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1493 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1494 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001495#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001496};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001499#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001500/*
1501 * AES-CFB128 test vectors from:
1502 *
1503 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1504 */
Yanray Wang62c99912023-05-11 11:06:53 +08001505static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001506{
1507 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1508 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001509#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001510 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1511 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1512 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1513 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1514 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1515 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1516 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001517#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001518};
1519
1520static const unsigned char aes_test_cfb128_iv[16] =
1521{
1522 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1523 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1524};
1525
1526static const unsigned char aes_test_cfb128_pt[64] =
1527{
1528 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1529 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1530 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1531 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1532 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1533 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1534 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1535 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1536};
1537
Yanray Wang62c99912023-05-11 11:06:53 +08001538static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001539{
1540 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1541 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1542 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1543 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1544 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1545 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1546 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1547 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001548#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001549 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1550 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1551 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1552 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1553 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1554 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1555 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1556 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1557 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1558 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1559 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1560 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1561 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1562 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1563 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1564 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001565#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001566};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001567#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001568
Simon Butcherad4e4932018-04-29 00:43:47 +01001569#if defined(MBEDTLS_CIPHER_MODE_OFB)
1570/*
1571 * AES-OFB test vectors from:
1572 *
Simon Butcher5db13622018-06-04 22:11:25 +01001573 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001574 */
Yanray Wang62c99912023-05-11 11:06:53 +08001575static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001576{
1577 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1578 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001579#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001580 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1581 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1582 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1583 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1584 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1585 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1586 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001587#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001588};
1589
1590static const unsigned char aes_test_ofb_iv[16] =
1591{
1592 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1593 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1594};
1595
1596static const unsigned char aes_test_ofb_pt[64] =
1597{
1598 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1599 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1600 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1601 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1602 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1603 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1604 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1605 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1606};
1607
Yanray Wang62c99912023-05-11 11:06:53 +08001608static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001609{
1610 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1611 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1612 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1613 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1614 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1615 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1616 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1617 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001618#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001619 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1620 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1621 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1622 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1623 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1624 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1625 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1626 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1627 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1628 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1629 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1630 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1631 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1632 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1633 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1634 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001635#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001636};
1637#endif /* MBEDTLS_CIPHER_MODE_OFB */
1638
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001639#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001640/*
1641 * AES-CTR test vectors from:
1642 *
1643 * http://www.faqs.org/rfcs/rfc3686.html
1644 */
1645
Yanray Wang62c99912023-05-11 11:06:53 +08001646static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001647{
1648 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1649 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1650 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1651 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1652 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1653 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1654};
1655
Yanray Wang62c99912023-05-11 11:06:53 +08001656static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001657{
1658 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1660 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1661 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1662 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1663 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1664};
1665
Yanray Wang62c99912023-05-11 11:06:53 +08001666static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001667{
1668 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1669 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001670 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1671 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1672 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1673 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1674
1675 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1676 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1677 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1678 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1679 0x20, 0x21, 0x22, 0x23 }
1680};
1681
Yanray Wang62c99912023-05-11 11:06:53 +08001682static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001683{
1684 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1685 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1686 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1687 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1688 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1689 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1690 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1691 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1692 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1693 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1694 0x25, 0xB2, 0x07, 0x2F }
1695};
1696
1697static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001698{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001699#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001700
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001701#if defined(MBEDTLS_CIPHER_MODE_XTS)
1702/*
1703 * AES-XTS test vectors from:
1704 *
1705 * IEEE P1619/D16 Annex B
1706 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1707 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1708 */
1709static const unsigned char aes_test_xts_key[][32] =
1710{
1711 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1715 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1716 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1717 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1718 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1719 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1720 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1721 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1722 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1723};
1724
1725static const unsigned char aes_test_xts_pt32[][32] =
1726{
1727 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1728 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1731 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1732 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1733 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1734 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1735 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1736 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1737 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1738 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1739};
1740
1741static const unsigned char aes_test_xts_ct32[][32] =
1742{
1743 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1744 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1745 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1746 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1747 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1748 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1749 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1750 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1751 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1752 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1753 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1754 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1755};
1756
1757static const unsigned char aes_test_xts_data_unit[][16] =
1758{
Gilles Peskine449bd832023-01-11 14:50:10 +01001759 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1761 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1762 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1763 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001765};
1766
1767#endif /* MBEDTLS_CIPHER_MODE_XTS */
1768
Paul Bakker5121ce52009-01-03 21:22:43 +00001769/*
1770 * Checkup routine
1771 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001772int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001773{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001774 int ret = 0, i, j, u, mode;
1775 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001776 unsigned char key[32];
1777 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001778 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001779#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1780 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001781 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001782#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001783#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001784 unsigned char prv[16];
1785#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001786#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1787 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001788 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001789#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001790#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001791 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001792#endif
1793#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001794 unsigned char nonce_counter[16];
1795 unsigned char stream_block[16];
1796#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001797 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001798
Gilles Peskine449bd832023-01-11 14:50:10 +01001799 memset(key, 0, 32);
1800 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001801
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001802 if (verbose != 0) {
1803#if defined(MBEDTLS_AES_ALT)
1804 mbedtls_printf(" AES note: alternative implementation.\n");
1805#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001806#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001807#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001808 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001809#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001810 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001811#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001812#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001813#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001814 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1815 mbedtls_printf(" AES note: using AESNI.\n");
1816 } else
1817#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001818#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001819 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001820 mbedtls_printf(" AES note: using AESCE.\n");
1821 } else
1822#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001823 {
1824#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1825 mbedtls_printf(" AES note: built-in implementation.\n");
1826#endif
1827 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001828#endif /* MBEDTLS_AES_ALT */
1829 }
1830
Paul Bakker5121ce52009-01-03 21:22:43 +00001831 /*
1832 * ECB mode
1833 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001834 {
1835 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001836 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001837
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001838 for (i = 0; i < num_tests << 1; i++) {
1839 u = i >> 1;
1840 keybits = 128 + u * 64;
1841 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001842
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001843 if (verbose != 0) {
1844 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1845 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1846 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001847#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001848 if (mode == MBEDTLS_AES_DECRYPT) {
1849 if (verbose != 0) {
1850 mbedtls_printf("skipped\n");
1851 }
1852 continue;
1853 }
1854#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001855
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001856 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001857
Yanray Wangb67b4742023-10-31 17:10:32 +08001858#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001859 if (mode == MBEDTLS_AES_DECRYPT) {
1860 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1861 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001862 } else
1863#endif
1864 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001865 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1866 aes_tests = aes_test_ecb_enc[u];
1867 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001868
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001869 /*
1870 * AES-192 is an optional feature that may be unavailable when
1871 * there is an alternative underlying implementation i.e. when
1872 * MBEDTLS_AES_ALT is defined.
1873 */
1874 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1875 mbedtls_printf("skipped\n");
1876 continue;
1877 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001878 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001879 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001880
1881 for (j = 0; j < 10000; j++) {
1882 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1883 if (ret != 0) {
1884 goto exit;
1885 }
1886 }
1887
1888 if (memcmp(buf, aes_tests, 16) != 0) {
1889 ret = 1;
1890 goto exit;
1891 }
1892
1893 if (verbose != 0) {
1894 mbedtls_printf("passed\n");
1895 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001896 }
1897
Gilles Peskine449bd832023-01-11 14:50:10 +01001898 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001899 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001900 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001901 }
1902
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001903#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001904 /*
1905 * CBC mode
1906 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001907 {
1908 static const int num_tests =
1909 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001910
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001911 for (i = 0; i < num_tests << 1; i++) {
1912 u = i >> 1;
1913 keybits = 128 + u * 64;
1914 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001915
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001916 if (verbose != 0) {
1917 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1918 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001919 }
1920
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001921 memset(iv, 0, 16);
1922 memset(prv, 0, 16);
1923 memset(buf, 0, 16);
1924
1925 if (mode == MBEDTLS_AES_DECRYPT) {
1926 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1927 aes_tests = aes_test_cbc_dec[u];
1928 } else {
1929 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1930 aes_tests = aes_test_cbc_enc[u];
1931 }
1932
1933 /*
1934 * AES-192 is an optional feature that may be unavailable when
1935 * there is an alternative underlying implementation i.e. when
1936 * MBEDTLS_AES_ALT is defined.
1937 */
1938 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1939 mbedtls_printf("skipped\n");
1940 continue;
1941 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001942 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001943 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001944
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001945 for (j = 0; j < 10000; j++) {
1946 if (mode == MBEDTLS_AES_ENCRYPT) {
1947 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001948
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001949 memcpy(tmp, prv, 16);
1950 memcpy(prv, buf, 16);
1951 memcpy(buf, tmp, 16);
1952 }
1953
1954 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1955 if (ret != 0) {
1956 goto exit;
1957 }
1958
1959 }
1960
1961 if (memcmp(buf, aes_tests, 16) != 0) {
1962 ret = 1;
1963 goto exit;
1964 }
1965
1966 if (verbose != 0) {
1967 mbedtls_printf("passed\n");
1968 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001969 }
1970
Gilles Peskine449bd832023-01-11 14:50:10 +01001971 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001972 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001973 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001974 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001975#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001977#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001978 /*
1979 * CFB128 mode
1980 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001981 {
1982 static const int num_tests =
1983 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00001984
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001985 for (i = 0; i < num_tests << 1; i++) {
1986 u = i >> 1;
1987 keybits = 128 + u * 64;
1988 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001989
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001990 if (verbose != 0) {
1991 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1992 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1993 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001994
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001995 memcpy(iv, aes_test_cfb128_iv, 16);
1996 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001997
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001998 offset = 0;
1999 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2000 /*
2001 * AES-192 is an optional feature that may be unavailable when
2002 * there is an alternative underlying implementation i.e. when
2003 * MBEDTLS_AES_ALT is defined.
2004 */
2005 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2006 mbedtls_printf("skipped\n");
2007 continue;
2008 } else if (ret != 0) {
2009 goto exit;
2010 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002011
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002012 if (mode == MBEDTLS_AES_DECRYPT) {
2013 memcpy(buf, aes_test_cfb128_ct[u], 64);
2014 aes_tests = aes_test_cfb128_pt;
2015 } else {
2016 memcpy(buf, aes_test_cfb128_pt, 64);
2017 aes_tests = aes_test_cfb128_ct[u];
2018 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002019
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002020 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2021 if (ret != 0) {
2022 goto exit;
2023 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002024
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002025 if (memcmp(buf, aes_tests, 64) != 0) {
2026 ret = 1;
2027 goto exit;
2028 }
2029
2030 if (verbose != 0) {
2031 mbedtls_printf("passed\n");
2032 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002033 }
2034
Gilles Peskine449bd832023-01-11 14:50:10 +01002035 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002036 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002037 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002040
Simon Butcherad4e4932018-04-29 00:43:47 +01002041#if defined(MBEDTLS_CIPHER_MODE_OFB)
2042 /*
2043 * OFB mode
2044 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002045 {
2046 static const int num_tests =
2047 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002048
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002049 for (i = 0; i < num_tests << 1; i++) {
2050 u = i >> 1;
2051 keybits = 128 + u * 64;
2052 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002053
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002054 if (verbose != 0) {
2055 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2056 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2057 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002058
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002059 memcpy(iv, aes_test_ofb_iv, 16);
2060 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002061
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002062 offset = 0;
2063 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2064 /*
2065 * AES-192 is an optional feature that may be unavailable when
2066 * there is an alternative underlying implementation i.e. when
2067 * MBEDTLS_AES_ALT is defined.
2068 */
2069 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2070 mbedtls_printf("skipped\n");
2071 continue;
2072 } else if (ret != 0) {
2073 goto exit;
2074 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002075
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002076 if (mode == MBEDTLS_AES_DECRYPT) {
2077 memcpy(buf, aes_test_ofb_ct[u], 64);
2078 aes_tests = aes_test_ofb_pt;
2079 } else {
2080 memcpy(buf, aes_test_ofb_pt, 64);
2081 aes_tests = aes_test_ofb_ct[u];
2082 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002083
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002084 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2085 if (ret != 0) {
2086 goto exit;
2087 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002088
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002089 if (memcmp(buf, aes_tests, 64) != 0) {
2090 ret = 1;
2091 goto exit;
2092 }
2093
2094 if (verbose != 0) {
2095 mbedtls_printf("passed\n");
2096 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002097 }
2098
Gilles Peskine449bd832023-01-11 14:50:10 +01002099 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002100 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002101 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002102 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002103#endif /* MBEDTLS_CIPHER_MODE_OFB */
2104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002105#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002106 /*
2107 * CTR mode
2108 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002109 {
2110 static const int num_tests =
2111 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002112
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002113 for (i = 0; i < num_tests << 1; i++) {
2114 u = i >> 1;
2115 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002116
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002117 if (verbose != 0) {
2118 mbedtls_printf(" AES-CTR-128 (%s): ",
2119 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2120 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002121
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002122 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2123 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002124
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002125 offset = 0;
2126 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2127 goto exit;
2128 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002129
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002130 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002131
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002132 if (mode == MBEDTLS_AES_DECRYPT) {
2133 memcpy(buf, aes_test_ctr_ct[u], len);
2134 aes_tests = aes_test_ctr_pt[u];
2135 } else {
2136 memcpy(buf, aes_test_ctr_pt[u], len);
2137 aes_tests = aes_test_ctr_ct[u];
2138 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002139
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002140 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2141 stream_block, buf, buf);
2142 if (ret != 0) {
2143 goto exit;
2144 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002145
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002146 if (memcmp(buf, aes_tests, len) != 0) {
2147 ret = 1;
2148 goto exit;
2149 }
2150
2151 if (verbose != 0) {
2152 mbedtls_printf("passed\n");
2153 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002154 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002155 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002156
Gilles Peskine449bd832023-01-11 14:50:10 +01002157 if (verbose != 0) {
2158 mbedtls_printf("\n");
2159 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002160#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002161
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002162#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002163 /*
2164 * XTS mode
2165 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002166 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002167 static const int num_tests =
2168 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2169 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002170
Gilles Peskine449bd832023-01-11 14:50:10 +01002171 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002172
Gilles Peskine449bd832023-01-11 14:50:10 +01002173 for (i = 0; i < num_tests << 1; i++) {
2174 const unsigned char *data_unit;
2175 u = i >> 1;
2176 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002177
Gilles Peskine449bd832023-01-11 14:50:10 +01002178 if (verbose != 0) {
2179 mbedtls_printf(" AES-XTS-128 (%s): ",
2180 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2181 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002182
Gilles Peskine449bd832023-01-11 14:50:10 +01002183 memset(key, 0, sizeof(key));
2184 memcpy(key, aes_test_xts_key[u], 32);
2185 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002186
Gilles Peskine449bd832023-01-11 14:50:10 +01002187 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002188
Gilles Peskine449bd832023-01-11 14:50:10 +01002189 if (mode == MBEDTLS_AES_DECRYPT) {
2190 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2191 if (ret != 0) {
2192 goto exit;
2193 }
2194 memcpy(buf, aes_test_xts_ct32[u], len);
2195 aes_tests = aes_test_xts_pt32[u];
2196 } else {
2197 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2198 if (ret != 0) {
2199 goto exit;
2200 }
2201 memcpy(buf, aes_test_xts_pt32[u], len);
2202 aes_tests = aes_test_xts_ct32[u];
2203 }
2204
2205
2206 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2207 buf, buf);
2208 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002209 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002210 }
2211
2212 if (memcmp(buf, aes_tests, len) != 0) {
2213 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002214 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002215 }
2216
2217 if (verbose != 0) {
2218 mbedtls_printf("passed\n");
2219 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002220 }
2221
Gilles Peskine449bd832023-01-11 14:50:10 +01002222 if (verbose != 0) {
2223 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002224 }
2225
Gilles Peskine449bd832023-01-11 14:50:10 +01002226 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002227 }
2228#endif /* MBEDTLS_CIPHER_MODE_XTS */
2229
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002230 ret = 0;
2231
2232exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002233 if (ret != 0 && verbose != 0) {
2234 mbedtls_printf("failed\n");
2235 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002236
Gilles Peskine449bd832023-01-11 14:50:10 +01002237 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002238
Gilles Peskine449bd832023-01-11 14:50:10 +01002239 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002240}
2241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002242#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002244#endif /* MBEDTLS_AES_C */