blob: f91d2519f5b8039db29d6dd58ac78d9b480aacf6 [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010022 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000023 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Dave Rodgman782df0352023-09-29 12:57:52 +010037#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
38#if !((defined(MBEDTLS_ARCH_IS_ARM64) && defined(MBEDTLS_AESCE_C)) || \
Dave Rodgmana06d45e2023-09-29 18:59:34 +010039 (defined(MBEDTLS_ARCH_IS_X64) && defined(MBEDTLS_AESNI_C)) || \
40 (defined(MBEDTLS_ARCH_IS_X86) && defined(MBEDTLS_AESNI_C)))
Jerry Yu69436812023-04-25 11:08:30 +080041#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080042#endif
43#endif
44
Dave Rodgmane81a6322023-09-29 13:54:27 +010045#if defined(MBEDTLS_ARCH_IS_X86)
Jerry Yu61fc5ed2023-08-18 17:28:48 +080046#if defined(MBEDTLS_PADLOCK_C)
47#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080048#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
49#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080050#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
51#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
52 "MBEDTLS_PADLOCK_C is set"
53#endif
54#endif
Jerry Yu02b15192023-04-23 14:43:19 +080055#endif
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000058#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000059#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000061#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010062#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080063#if defined(MBEDTLS_AESCE_C)
64#include "aesce.h"
65#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000066
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068
Yanray Wangf03b4912023-11-09 11:23:17 +080069/*
70 * This is a convenience shorthand macro to check if we need reverse S-box and
71 * reverse tables. It's private and only defined in this file.
72 */
73#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \
74 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \
Yanray Wangb67b4742023-10-31 17:10:32 +080075 !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wangdbcc0c62023-08-30 15:04:01 +080076#define MBEDTLS_AES_NEED_REVERSE_TABLES
77#endif
78
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020080
Jerry Yu9e628622023-08-17 11:20:09 +080081#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000082static int aes_padlock_ace = -1;
83#endif
84
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020085#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000086/*
87 * Forward S-box
88 */
Dave Rodgman18ddf612023-10-04 14:03:12 +010089MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +000090{
91 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
92 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
93 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
94 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
95 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
96 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
97 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
98 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
99 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
100 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
101 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
102 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
103 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
104 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
105 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
106 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
107 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
108 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
109 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
110 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
111 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
112 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
113 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
114 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
115 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
116 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
117 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
118 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
119 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
120 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
121 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
122 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
123};
124
125/*
126 * Forward tables
127 */
128#define FT \
129\
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
131 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
132 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
133 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
134 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
135 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
136 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
137 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
138 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
139 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
140 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
141 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
142 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
143 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
144 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
145 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
146 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
147 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
148 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
149 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
150 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
151 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
152 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
153 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
154 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
155 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
156 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
157 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
158 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
159 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
160 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
161 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
162 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
163 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
164 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
165 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
166 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
167 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
168 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
169 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
170 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
171 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
172 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
173 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
174 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
175 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
176 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
177 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
178 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
179 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
180 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
181 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
182 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
183 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
184 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
185 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
186 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
187 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
188 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
189 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
190 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
191 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
192 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
193 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 +0000194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100196MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000197#undef V
198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100200MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000201#undef V
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100204MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000205#undef V
206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100208MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000209#undef V
210
211#undef FT
212
213/*
214 * Reverse S-box
215 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100216MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000217{
218 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
219 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
220 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
221 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
222 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
223 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
224 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
225 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
226 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
227 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
228 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
229 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
230 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
231 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
232 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
233 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
234 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
235 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
236 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
237 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
238 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
239 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
240 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
241 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
242 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
243 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
244 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
245 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
246 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
247 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
248 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
249 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
250};
251
252/*
253 * Reverse tables
254 */
255#define RT \
256\
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
258 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
259 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
260 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
261 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
262 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
263 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
264 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
265 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
266 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
267 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
268 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
269 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
270 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
271 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
272 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
273 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
274 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
275 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
276 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
277 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
278 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
279 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
280 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
281 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
282 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
283 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
284 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
285 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
286 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
287 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
288 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
289 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
290 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
291 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
292 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
293 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
294 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
295 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
296 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
297 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
298 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
299 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
300 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
301 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
302 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
303 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
304 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
305 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
306 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
307 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
308 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
309 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
310 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
311 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
312 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
313 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
314 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
315 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
316 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
317 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
318 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
319 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
320 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 +0000321
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100324MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000325#undef V
326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100328MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000329#undef V
330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100332MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000333#undef V
334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100336MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000337#undef V
338
339#undef RT
340
341/*
342 * Round constants
343 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100344MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000345{
346 0x00000001, 0x00000002, 0x00000004, 0x00000008,
347 0x00000010, 0x00000020, 0x00000040, 0x00000080,
348 0x0000001B, 0x00000036
349};
350
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000352
353/*
354 * Forward S-box & tables
355 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100356MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
357MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
358MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
359MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
360MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
362/*
363 * Reverse S-box & tables
364 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100365MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100366
Dave Rodgman18ddf612023-10-04 14:03:12 +0100367MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
368MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
369MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
370MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
372/*
373 * Round constants
374 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100375MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
377/*
378 * Tables generation code
379 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100380#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
381#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
382#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
Dave Rodgman18ddf612023-10-04 14:03:12 +0100384MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
Dave Rodgman18ddf612023-10-04 14:03:12 +0100386MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000387{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800388 int i;
389 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800390 uint8_t pow[256];
391 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000392
393 /*
394 * compute pow and log tables over GF(2^8)
395 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100396 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000397 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800398 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800399 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000400 }
401
402 /*
403 * calculate the round constants
404 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200406 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800407 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 }
409
410 /*
411 * generate the forward and reverse S-boxes
412 */
413 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800414#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800416#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 x = pow[255 - log[i]];
420
Yanray Wangfe944ce2023-06-26 18:16:01 +0800421 y = x; y = (y << 1) | (y >> 7);
422 x ^= y; y = (y << 1) | (y >> 7);
423 x ^= y; y = (y << 1) | (y >> 7);
424 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 x ^= y ^ 0x63;
426
Yanray Wangfe944ce2023-06-26 18:16:01 +0800427 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800428#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800430#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 }
432
433 /*
434 * generate the forward and reverse tables
435 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800438 y = XTIME(x);
439 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 FT0[i] = ((uint32_t) y) ^
442 ((uint32_t) x << 8) ^
443 ((uint32_t) x << 16) ^
444 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
Hanno Beckerad049a92017-06-19 16:31:54 +0100446#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 FT1[i] = ROTL8(FT0[i]);
448 FT2[i] = ROTL8(FT1[i]);
449 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100450#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800452#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 x = RSb[i];
454
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
456 ((uint32_t) MUL(0x09, x) << 8) ^
457 ((uint32_t) MUL(0x0D, x) << 16) ^
458 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
Hanno Beckerad049a92017-06-19 16:31:54 +0100460#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 RT1[i] = ROTL8(RT0[i]);
462 RT2[i] = ROTL8(RT1[i]);
463 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100464#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800465#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 }
467}
468
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200469#undef ROTL8
470
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
Hanno Beckerad049a92017-06-19 16:31:54 +0100473#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200474
Gilles Peskine449bd832023-01-11 14:50:10 +0100475#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
476#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
477#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200478
479#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100480#define AES_RT1(idx) ROTL8(RT0[idx])
481#define AES_RT2(idx) ROTL16(RT0[idx])
482#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200483
484#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100485#define AES_FT1(idx) ROTL8(FT0[idx])
486#define AES_FT2(idx) ROTL16(FT0[idx])
487#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200488
Hanno Becker177d3cf2017-06-07 15:52:48 +0100489#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200490
491#define AES_RT0(idx) RT0[idx]
492#define AES_RT1(idx) RT1[idx]
493#define AES_RT2(idx) RT2[idx]
494#define AES_RT3(idx) RT3[idx]
495
496#define AES_FT0(idx) FT0[idx]
497#define AES_FT1(idx) FT1[idx]
498#define AES_FT2(idx) FT2[idx]
499#define AES_FT3(idx) FT3[idx]
500
Hanno Becker177d3cf2017-06-07 15:52:48 +0100501#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200504{
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200506}
507
Gilles Peskine449bd832023-01-11 14:50:10 +0100508void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200509{
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200511 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200513
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200515}
516
Jaeden Amero9366feb2018-05-29 18:55:17 +0100517#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100518void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100519{
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 mbedtls_aes_init(&ctx->crypt);
521 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100522}
523
Gilles Peskine449bd832023-01-11 14:50:10 +0100524void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100525{
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100527 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 }
Simon Butcher5201e412018-12-06 17:40:14 +0000529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 mbedtls_aes_free(&ctx->crypt);
531 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100532}
533#endif /* MBEDTLS_CIPHER_MODE_XTS */
534
Gilles Peskine0de8f852023-03-16 17:14:59 +0100535/* Some implementations need the round keys to be aligned.
536 * Return an offset to be added to buf, such that (buf + offset) is
537 * correctly aligned.
538 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
539 * i.e. an offset of 1 means 4 bytes and so on.
540 */
Jerry Yu96084472023-08-17 18:10:45 +0800541#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100542 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100543#define MAY_NEED_TO_ALIGN
544#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100545
Dave Rodgman18ddf612023-10-04 14:03:12 +0100546MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100547{
548#if defined(MAY_NEED_TO_ALIGN)
549 int align_16_bytes = 0;
550
Jerry Yu9e628622023-08-17 11:20:09 +0800551#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100552 if (aes_padlock_ace == -1) {
553 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
554 }
555 if (aes_padlock_ace) {
556 align_16_bytes = 1;
557 }
558#endif
559
Gilles Peskine9c682e72023-03-16 17:21:33 +0100560#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100561 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
562 align_16_bytes = 1;
563 }
564#endif
565
566 if (align_16_bytes) {
567 /* These implementations needs 16-byte alignment
568 * for the round key array. */
569 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
570 if (delta == 0) {
571 return 0;
572 } else {
573 return 4 - delta; // 16 bytes = 4 uint32_t
574 }
575 }
576#else /* MAY_NEED_TO_ALIGN */
577 (void) buf;
578#endif /* MAY_NEED_TO_ALIGN */
579
580 return 0;
581}
582
Paul Bakker5121ce52009-01-03 21:22:43 +0000583/*
584 * AES key schedule (encryption)
585 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200586#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100587int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
588 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000589{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000590 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800594#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 case 192: ctx->nr = 12; break;
596 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800597#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000599 }
600
Simon Butcher5201e412018-12-06 17:40:14 +0000601#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000603 aes_gen_tables();
604 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000605 }
606#endif
607
Gilles Peskine0de8f852023-03-16 17:14:59 +0100608 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100609 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100611#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
613 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
614 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100615#endif
616
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800617#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100618 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800619 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
620 }
621#endif
622
Jerry Yu29c91ba2023-08-04 11:02:04 +0800623#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800624 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000626 }
627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 case 10:
630
Jerry Yu3a0f0442023-08-17 17:06:21 +0800631 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200632 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
634 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
635 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
636 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
638 RK[5] = RK[1] ^ RK[4];
639 RK[6] = RK[2] ^ RK[5];
640 RK[7] = RK[3] ^ RK[6];
641 }
642 break;
643
Arto Kinnunen732ca322023-04-14 14:26:10 +0800644#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000645 case 12:
646
Jerry Yu3a0f0442023-08-17 17:06:21 +0800647 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200648 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
650 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
651 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
652 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000653
654 RK[7] = RK[1] ^ RK[6];
655 RK[8] = RK[2] ^ RK[7];
656 RK[9] = RK[3] ^ RK[8];
657 RK[10] = RK[4] ^ RK[9];
658 RK[11] = RK[5] ^ RK[10];
659 }
660 break;
661
662 case 14:
663
Jerry Yu3a0f0442023-08-17 17:06:21 +0800664 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200665 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
667 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
668 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
669 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
671 RK[9] = RK[1] ^ RK[8];
672 RK[10] = RK[2] ^ RK[9];
673 RK[11] = RK[3] ^ RK[10];
674
675 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
677 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
678 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
679 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
681 RK[13] = RK[5] ^ RK[12];
682 RK[14] = RK[6] ^ RK[13];
683 RK[15] = RK[7] ^ RK[14];
684 }
685 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800686#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000687 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800690#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000691}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200692#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
694/*
695 * AES key schedule (decryption)
696 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800697#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100698int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
699 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000700{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800701#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800702 uint32_t *SK;
703#endif
704 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000706 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800707
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200708
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Gilles Peskine0de8f852023-03-16 17:14:59 +0100711 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100712 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200714 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100715 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200716 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000718
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200719 ctx->nr = cty.nr;
720
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100721#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
723 mbedtls_aesni_inverse_key((unsigned char *) RK,
724 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200725 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100726 }
727#endif
728
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800729#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100730 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800731 mbedtls_aesce_inverse_key(
732 (unsigned char *) RK,
733 (const unsigned char *) (cty.buf + cty.rk_offset),
734 ctx->nr);
735 goto exit;
736 }
737#endif
738
Jerry Yu29c91ba2023-08-04 11:02:04 +0800739#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100740 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000741
742 *RK++ = *SK++;
743 *RK++ = *SK++;
744 *RK++ = *SK++;
745 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800746 SK -= 8;
747 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
748 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
750 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
751 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
752 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000753 }
754 }
755
756 *RK++ = *SK++;
757 *RK++ = *SK++;
758 *RK++ = *SK++;
759 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800760#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200761exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000763
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000765}
Yanray Wangb67b4742023-10-31 17:10:32 +0800766#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100767
768#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100769static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
770 unsigned int keybits,
771 const unsigned char **key1,
772 unsigned int *key1bits,
773 const unsigned char **key2,
774 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100775{
776 const unsigned int half_keybits = keybits / 2;
777 const unsigned int half_keybytes = half_keybits / 8;
778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100780 case 256: break;
781 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100783 }
784
785 *key1bits = half_keybits;
786 *key2bits = half_keybits;
787 *key1 = &key[0];
788 *key2 = &key[half_keybytes];
789
790 return 0;
791}
792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
794 const unsigned char *key,
795 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100796{
Janos Follath24eed8d2019-11-22 13:21:35 +0000797 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100798 const unsigned char *key1, *key2;
799 unsigned int key1bits, key2bits;
800
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
802 &key2, &key2bits);
803 if (ret != 0) {
804 return ret;
805 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100806
807 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
809 if (ret != 0) {
810 return ret;
811 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100812
813 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100815}
816
Gilles Peskine449bd832023-01-11 14:50:10 +0100817int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
818 const unsigned char *key,
819 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100820{
Janos Follath24eed8d2019-11-22 13:21:35 +0000821 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100822 const unsigned char *key1, *key2;
823 unsigned int key1bits, key2bits;
824
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
826 &key2, &key2bits);
827 if (ret != 0) {
828 return ret;
829 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100830
831 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
833 if (ret != 0) {
834 return ret;
835 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100836
837 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100839}
840#endif /* MBEDTLS_CIPHER_MODE_XTS */
841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100843 do \
844 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
846 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
847 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
848 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100849 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
851 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
852 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
853 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100854 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
856 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
857 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
858 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100859 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
861 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
862 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
863 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
864 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100867 do \
868 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
870 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
871 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
872 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100873 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
875 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
876 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
877 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100878 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
880 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
881 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
882 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100883 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
885 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
886 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
887 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
888 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000889
890/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200891 * AES-ECB block encryption
892 */
893#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100894int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
895 const unsigned char input[16],
896 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200897{
898 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100899 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200901 uint32_t X[4];
902 uint32_t Y[4];
903 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200904
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
906 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
907 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
908 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
911 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]);
912 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 +0200913 }
914
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 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 +0200916
Gilles Peskine5197c662020-08-26 17:03:24 +0200917 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
919 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
920 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
921 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200922
Gilles Peskine5197c662020-08-26 17:03:24 +0200923 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
925 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
926 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
927 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200928
Gilles Peskine5197c662020-08-26 17:03:24 +0200929 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
931 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
932 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
933 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934
Gilles Peskine5197c662020-08-26 17:03:24 +0200935 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
937 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
938 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
939 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200940
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
942 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
943 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
944 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200949}
950#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
951
952/*
953 * AES-ECB block decryption
954 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800955#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100956int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
957 const unsigned char input[16],
958 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200959{
960 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100961 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200963 uint32_t X[4];
964 uint32_t Y[4];
965 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200966
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
968 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
969 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
970 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200971
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
973 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]);
974 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 +0200975 }
976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 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 +0200978
Gilles Peskine5197c662020-08-26 17:03:24 +0200979 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
981 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
982 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200984
Gilles Peskine5197c662020-08-26 17:03:24 +0200985 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
987 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
988 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200990
Gilles Peskine5197c662020-08-26 17:03:24 +0200991 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
993 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
994 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
995 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996
Gilles Peskine5197c662020-08-26 17:03:24 +0200997 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
999 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1000 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1001 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1004 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1005 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1006 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001011}
Yanray Wangb67b4742023-10-31 17:10:32 +08001012#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001013
Gilles Peskine148cad12023-03-16 13:08:42 +01001014/* VIA Padlock and our intrinsics-based implementation of AESNI require
1015 * the round keys to be aligned on a 16-byte boundary. We take care of this
1016 * before creating them, but the AES context may have moved (this can happen
1017 * if the library is called from a language with managed memory), and in later
1018 * calls it might have a different alignment with respect to 16-byte memory.
1019 * So we may need to realign.
1020 */
Dave Rodgman18ddf612023-10-04 14:03:12 +01001021MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +01001022{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001023 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1024 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001025 memmove(ctx->buf + new_offset, // new address
1026 ctx->buf + ctx->rk_offset, // current address
1027 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1028 ctx->rk_offset = new_offset;
1029 }
1030}
Gilles Peskine148cad12023-03-16 13:08:42 +01001031
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001032/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001033 * AES-ECB block encryption/decryption
1034 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001035int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1036 int mode,
1037 const unsigned char input[16],
1038 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001039{
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001041 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001043
Gilles Peskine0de8f852023-03-16 17:14:59 +01001044#if defined(MAY_NEED_TO_ALIGN)
1045 aes_maybe_realign(ctx);
1046#endif
1047
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001048#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1050 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1051 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001052#endif
1053
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001054#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001055 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001056 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1057 }
1058#endif
1059
Jerry Yu9e628622023-08-17 11:20:09 +08001060#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001062 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 }
1064#endif
1065
Jerry Yu29c91ba2023-08-04 11:02:04 +08001066#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001067#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang111159b2023-11-10 13:41:12 +08001068 if (mode == MBEDTLS_AES_DECRYPT) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang111159b2023-11-10 13:41:12 +08001070 } else
Jerry Yu29c91ba2023-08-04 11:02:04 +08001071#endif
Yanray Wang111159b2023-11-10 13:41:12 +08001072 {
1073 return mbedtls_internal_aes_encrypt(ctx, input, output);
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001074 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001075#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001076}
1077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001079
Paul Bakker5121ce52009-01-03 21:22:43 +00001080/*
1081 * AES-CBC buffer encryption/decryption
1082 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001083int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1084 int mode,
1085 size_t length,
1086 unsigned char iv[16],
1087 const unsigned char *input,
1088 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001089{
Gilles Peskine7820a572021-07-07 21:08:28 +02001090 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001091 unsigned char temp[16];
1092
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001094 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001096
Paul Elliott2ad93672023-08-11 11:07:06 +01001097 /* Nothing to do if length is zero. */
1098 if (length == 0) {
1099 return 0;
1100 }
1101
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 if (length % 16) {
1103 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1104 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001105
Jerry Yu9e628622023-08-17 11:20:09 +08001106#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 if (aes_padlock_ace > 0) {
1108 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1109 return 0;
1110 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001111
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001112 // If padlock data misaligned, we just fall back to
1113 // unaccelerated mode
1114 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001115 }
1116#endif
1117
Dave Rodgman906c63c2023-06-14 17:53:51 +01001118 const unsigned char *ivp = iv;
1119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 if (mode == MBEDTLS_AES_DECRYPT) {
1121 while (length > 0) {
1122 memcpy(temp, input, 16);
1123 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1124 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001125 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001127 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001128 * the result for the next block in CBC, and the cost of transferring that data from
1129 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001130 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001131
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001133
1134 input += 16;
1135 output += 16;
1136 length -= 16;
1137 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 } else {
1139 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001140 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1143 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001144 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001146 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001147
1148 input += 16;
1149 output += 16;
1150 length -= 16;
1151 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001152 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001153 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001154 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001155
Gilles Peskine7820a572021-07-07 21:08:28 +02001156exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001158}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001160
Aorimn5f778012016-06-09 23:22:58 +02001161#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001162
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001163typedef unsigned char mbedtls_be128[16];
1164
1165/*
1166 * GF(2^128) multiplication function
1167 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001168 * This function multiplies a field element by x in the polynomial field
1169 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001170 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001171 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001172 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001173#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001174MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001175#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001176static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001177 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001178{
1179 uint64_t a, b, ra, rb;
1180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 a = MBEDTLS_GET_UINT64_LE(x, 0);
1182 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001183
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1185 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001186
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1188 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001189}
1190
Aorimn5f778012016-06-09 23:22:58 +02001191/*
1192 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001193 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001194 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001195 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001196 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001197#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001198MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001199#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001200int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1201 int mode,
1202 size_t length,
1203 const unsigned char data_unit[16],
1204 const unsigned char *input,
1205 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001206{
Janos Follath24eed8d2019-11-22 13:21:35 +00001207 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001208 size_t blocks = length / 16;
1209 size_t leftover = length % 16;
1210 unsigned char tweak[16];
1211 unsigned char prev_tweak[16];
1212 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001213
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001215 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001216 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001217
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001218 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001220 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 }
Aorimn5f778012016-06-09 23:22:58 +02001222
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001223 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001224 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001225 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 }
Aorimn5f778012016-06-09 23:22:58 +02001227
Jaeden Amerod82cd862018-04-28 15:02:45 +01001228 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1230 data_unit, tweak);
1231 if (ret != 0) {
1232 return ret;
1233 }
Aorimn5f778012016-06-09 23:22:58 +02001234
Gilles Peskine449bd832023-01-11 14:50:10 +01001235 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001236 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001237 /* We are on the last block in a decrypt operation that has
1238 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001239 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001240 * the leftovers and then update the current tweak for use on this,
1241 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 memcpy(prev_tweak, tweak, sizeof(tweak));
1243 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001244 }
1245
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001247
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1249 if (ret != 0) {
1250 return ret;
1251 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001254
1255 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001257
1258 output += 16;
1259 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001260 }
1261
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001263 /* If we are on the leftover bytes in a decrypt operation, we need to
1264 * use the previous tweak for these bytes (as saved in prev_tweak). */
1265 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001266
Jaeden Amerod82cd862018-04-28 15:02:45 +01001267 /* We are now on the final part of the data unit, which doesn't divide
1268 * evenly by 16. It's time for ciphertext stealing. */
1269 size_t i;
1270 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001271
Jaeden Amerod82cd862018-04-28 15:02:45 +01001272 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001273 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001276 }
Aorimn5f778012016-06-09 23:22:58 +02001277
Dave Rodgman069e7f42022-11-24 19:37:26 +00001278 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001280
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281 /* Copy ciphertext bytes from the previous block for input in this
1282 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001284
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1286 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001287 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 }
Aorimn5f778012016-06-09 23:22:58 +02001289
Jaeden Amerod82cd862018-04-28 15:02:45 +01001290 /* Write the result back to the previous block, overriding the previous
1291 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001293 }
1294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001296}
1297#endif /* MBEDTLS_CIPHER_MODE_XTS */
1298
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001299#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001300/*
1301 * AES-CFB128 buffer encryption/decryption
1302 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001303int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1304 int mode,
1305 size_t length,
1306 size_t *iv_off,
1307 unsigned char iv[16],
1308 const unsigned char *input,
1309 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001310{
Paul Bakker27fdf462011-06-09 13:55:13 +00001311 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001312 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001313 size_t n;
1314
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001316 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001318
1319 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001320
Gilles Peskine449bd832023-01-11 14:50:10 +01001321 if (n > 15) {
1322 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1323 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001324
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 if (mode == MBEDTLS_AES_DECRYPT) {
1326 while (length--) {
1327 if (n == 0) {
1328 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1329 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001330 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001332 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001333
1334 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 iv[n] = (unsigned char) c;
1337
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001339 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 } else {
1341 while (length--) {
1342 if (n == 0) {
1343 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1344 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001345 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001347 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001350
Gilles Peskine449bd832023-01-11 14:50:10 +01001351 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001352 }
1353 }
1354
1355 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001356 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001357
Gilles Peskine7820a572021-07-07 21:08:28 +02001358exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001360}
Paul Bakker556efba2014-01-24 15:38:12 +01001361
1362/*
1363 * AES-CFB8 buffer encryption/decryption
1364 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001365int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1366 int mode,
1367 size_t length,
1368 unsigned char iv[16],
1369 const unsigned char *input,
1370 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001371{
Gilles Peskine7820a572021-07-07 21:08:28 +02001372 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001373 unsigned char c;
1374 unsigned char ov[17];
1375
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001377 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 }
1379 while (length--) {
1380 memcpy(ov, iv, 16);
1381 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1382 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001383 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 }
Paul Bakker556efba2014-01-24 15:38:12 +01001385
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001387 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 }
Paul Bakker556efba2014-01-24 15:38:12 +01001389
Gilles Peskine449bd832023-01-11 14:50:10 +01001390 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001391
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001393 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001394 }
Paul Bakker556efba2014-01-24 15:38:12 +01001395
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001397 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001398 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001399
Gilles Peskine7820a572021-07-07 21:08:28 +02001400exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001401 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001402}
Simon Butcher76a5b222018-04-22 22:57:27 +01001403#endif /* MBEDTLS_CIPHER_MODE_CFB */
1404
1405#if defined(MBEDTLS_CIPHER_MODE_OFB)
1406/*
1407 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1408 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001409int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1410 size_t length,
1411 size_t *iv_off,
1412 unsigned char iv[16],
1413 const unsigned char *input,
1414 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001415{
Simon Butcherad4e4932018-04-29 00:43:47 +01001416 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001417 size_t n;
1418
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001419 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001420
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 if (n > 15) {
1422 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1423 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001424
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 while (length--) {
1426 if (n == 0) {
1427 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1428 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001429 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001430 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001431 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001432 *output++ = *input++ ^ iv[n];
1433
Gilles Peskine449bd832023-01-11 14:50:10 +01001434 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001435 }
1436
1437 *iv_off = n;
1438
Simon Butcherad4e4932018-04-29 00:43:47 +01001439exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001440 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001441}
1442#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001444#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001445/*
1446 * AES-CTR buffer encryption/decryption
1447 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001448int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1449 size_t length,
1450 size_t *nc_off,
1451 unsigned char nonce_counter[16],
1452 unsigned char stream_block[16],
1453 const unsigned char *input,
1454 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001455{
Paul Bakker369e14b2012-04-18 14:16:09 +00001456 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001457 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001458 size_t n;
1459
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001460 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001461
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 if (n > 0x0F) {
1463 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1464 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001465
Gilles Peskine449bd832023-01-11 14:50:10 +01001466 while (length--) {
1467 if (n == 0) {
1468 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1469 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001470 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001471 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001472
Gilles Peskine449bd832023-01-11 14:50:10 +01001473 for (i = 16; i > 0; i--) {
1474 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001475 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001476 }
1477 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001478 }
1479 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001480 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001481
Gilles Peskine449bd832023-01-11 14:50:10 +01001482 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483 }
1484
1485 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001486 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001487
Gilles Peskine7820a572021-07-07 21:08:28 +02001488exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001489 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001490}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001496/*
1497 * AES test vectors from:
1498 *
1499 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1500 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001501#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001502static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001503{
1504 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1505 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001506#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001507 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1508 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1509 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1510 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001511#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001512};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001513#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001514
Yanray Wang62c99912023-05-11 11:06:53 +08001515static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001516{
1517 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1518 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001519#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001520 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1521 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1522 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1523 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001524#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001525};
1526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001527#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001528static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001529{
1530 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1531 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001532#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001533 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1534 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1535 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1536 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001537#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001538};
1539
Yanray Wang62c99912023-05-11 11:06:53 +08001540static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001541{
1542 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1543 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001544#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001545 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1546 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1547 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1548 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001549#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001550};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001551#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001552
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001553#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001554/*
1555 * AES-CFB128 test vectors from:
1556 *
1557 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1558 */
Yanray Wang62c99912023-05-11 11:06:53 +08001559static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001560{
1561 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1562 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001563#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001564 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1565 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1566 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1567 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1568 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1569 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1570 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001571#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001572};
1573
1574static const unsigned char aes_test_cfb128_iv[16] =
1575{
1576 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1577 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1578};
1579
1580static const unsigned char aes_test_cfb128_pt[64] =
1581{
1582 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1583 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1584 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1585 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1586 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1587 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1588 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1589 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1590};
1591
Yanray Wang62c99912023-05-11 11:06:53 +08001592static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001593{
1594 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1595 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1596 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1597 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1598 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1599 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1600 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1601 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001602#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001603 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1604 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1605 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1606 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1607 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1608 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1609 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1610 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1611 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1612 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1613 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1614 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1615 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1616 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1617 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1618 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001619#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001620};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001621#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001622
Simon Butcherad4e4932018-04-29 00:43:47 +01001623#if defined(MBEDTLS_CIPHER_MODE_OFB)
1624/*
1625 * AES-OFB test vectors from:
1626 *
Simon Butcher5db13622018-06-04 22:11:25 +01001627 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001628 */
Yanray Wang62c99912023-05-11 11:06:53 +08001629static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001630{
1631 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1632 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001633#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001634 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1635 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1636 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1637 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1638 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1639 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1640 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001641#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001642};
1643
1644static const unsigned char aes_test_ofb_iv[16] =
1645{
1646 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1647 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1648};
1649
1650static const unsigned char aes_test_ofb_pt[64] =
1651{
1652 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1653 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1654 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1655 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1656 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1657 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1658 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1659 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1660};
1661
Yanray Wang62c99912023-05-11 11:06:53 +08001662static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001663{
1664 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1665 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1666 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1667 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1668 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1669 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1670 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1671 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001672#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001673 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1674 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1675 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1676 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1677 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1678 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1679 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1680 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1681 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1682 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1683 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1684 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1685 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1686 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1687 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1688 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001689#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001690};
1691#endif /* MBEDTLS_CIPHER_MODE_OFB */
1692
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001693#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001694/*
1695 * AES-CTR test vectors from:
1696 *
1697 * http://www.faqs.org/rfcs/rfc3686.html
1698 */
1699
Yanray Wang62c99912023-05-11 11:06:53 +08001700static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001701{
1702 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1703 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1704 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1705 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1706 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1707 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1708};
1709
Yanray Wang62c99912023-05-11 11:06:53 +08001710static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001711{
1712 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1714 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1715 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1716 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1717 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1718};
1719
Yanray Wang62c99912023-05-11 11:06:53 +08001720static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001721{
1722 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1723 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001724 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1725 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1726 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1727 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1728
1729 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1730 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1731 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1732 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1733 0x20, 0x21, 0x22, 0x23 }
1734};
1735
Yanray Wang62c99912023-05-11 11:06:53 +08001736static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001737{
1738 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1739 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1740 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1741 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1742 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1743 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1744 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1745 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1746 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1747 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1748 0x25, 0xB2, 0x07, 0x2F }
1749};
1750
1751static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001752{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001753#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001754
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001755#if defined(MBEDTLS_CIPHER_MODE_XTS)
1756/*
1757 * AES-XTS test vectors from:
1758 *
1759 * IEEE P1619/D16 Annex B
1760 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1761 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1762 */
1763static const unsigned char aes_test_xts_key[][32] =
1764{
1765 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1769 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1770 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1771 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1772 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1773 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1774 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1775 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1776 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1777};
1778
1779static const unsigned char aes_test_xts_pt32[][32] =
1780{
1781 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1785 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1786 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1787 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1788 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1789 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1790 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1791 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1792 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1793};
1794
1795static const unsigned char aes_test_xts_ct32[][32] =
1796{
1797 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1798 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1799 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1800 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1801 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1802 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1803 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1804 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1805 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1806 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1807 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1808 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1809};
1810
1811static const unsigned char aes_test_xts_data_unit[][16] =
1812{
Gilles Peskine449bd832023-01-11 14:50:10 +01001813 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1815 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1817 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001819};
1820
1821#endif /* MBEDTLS_CIPHER_MODE_XTS */
1822
Paul Bakker5121ce52009-01-03 21:22:43 +00001823/*
1824 * Checkup routine
1825 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001826int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001827{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001828 int ret = 0, i, j, u, mode;
1829 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001830 unsigned char key[32];
1831 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001832 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001833#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1834 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001835 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001836#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001837#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001838 unsigned char prv[16];
1839#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001840#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1841 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001842 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001843#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001844#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001845 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001846#endif
1847#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001848 unsigned char nonce_counter[16];
1849 unsigned char stream_block[16];
1850#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001851 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001852
Gilles Peskine449bd832023-01-11 14:50:10 +01001853 memset(key, 0, 32);
1854 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001855
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001856 if (verbose != 0) {
1857#if defined(MBEDTLS_AES_ALT)
1858 mbedtls_printf(" AES note: alternative implementation.\n");
1859#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001860#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001861#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001862 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001863#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001864 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001865#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001866#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001867#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001868 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1869 mbedtls_printf(" AES note: using AESNI.\n");
1870 } else
1871#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001872#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001873 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1874 mbedtls_printf(" AES note: using VIA Padlock.\n");
1875 } else
1876#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001877#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001878 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001879 mbedtls_printf(" AES note: using AESCE.\n");
1880 } else
1881#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001882 {
1883#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1884 mbedtls_printf(" AES note: built-in implementation.\n");
1885#endif
1886 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001887#endif /* MBEDTLS_AES_ALT */
1888 }
1889
Paul Bakker5121ce52009-01-03 21:22:43 +00001890 /*
1891 * ECB mode
1892 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001893 {
1894 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001895 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001897 for (i = 0; i < num_tests << 1; i++) {
1898 u = i >> 1;
1899 keybits = 128 + u * 64;
1900 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001901
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001902 if (verbose != 0) {
1903 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1904 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1905 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001906#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001907 if (mode == MBEDTLS_AES_DECRYPT) {
1908 if (verbose != 0) {
1909 mbedtls_printf("skipped\n");
1910 }
1911 continue;
1912 }
1913#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001914
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001915 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001916
Yanray Wangb67b4742023-10-31 17:10:32 +08001917#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001918 if (mode == MBEDTLS_AES_DECRYPT) {
1919 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1920 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001921 } else
1922#endif
1923 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001924 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1925 aes_tests = aes_test_ecb_enc[u];
1926 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001927
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001928 /*
1929 * AES-192 is an optional feature that may be unavailable when
1930 * there is an alternative underlying implementation i.e. when
1931 * MBEDTLS_AES_ALT is defined.
1932 */
1933 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1934 mbedtls_printf("skipped\n");
1935 continue;
1936 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001937 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001938 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001939
1940 for (j = 0; j < 10000; j++) {
1941 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1942 if (ret != 0) {
1943 goto exit;
1944 }
1945 }
1946
1947 if (memcmp(buf, aes_tests, 16) != 0) {
1948 ret = 1;
1949 goto exit;
1950 }
1951
1952 if (verbose != 0) {
1953 mbedtls_printf("passed\n");
1954 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001955 }
1956
Gilles Peskine449bd832023-01-11 14:50:10 +01001957 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001958 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001959 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001960 }
1961
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001962#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001963 /*
1964 * CBC mode
1965 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001966 {
1967 static const int num_tests =
1968 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001969
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001970 for (i = 0; i < num_tests << 1; i++) {
1971 u = i >> 1;
1972 keybits = 128 + u * 64;
1973 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001974
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001975 if (verbose != 0) {
1976 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1977 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001978 }
1979
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001980 memset(iv, 0, 16);
1981 memset(prv, 0, 16);
1982 memset(buf, 0, 16);
1983
1984 if (mode == MBEDTLS_AES_DECRYPT) {
1985 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1986 aes_tests = aes_test_cbc_dec[u];
1987 } else {
1988 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1989 aes_tests = aes_test_cbc_enc[u];
1990 }
1991
1992 /*
1993 * AES-192 is an optional feature that may be unavailable when
1994 * there is an alternative underlying implementation i.e. when
1995 * MBEDTLS_AES_ALT is defined.
1996 */
1997 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1998 mbedtls_printf("skipped\n");
1999 continue;
2000 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002001 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002002 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002003
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002004 for (j = 0; j < 10000; j++) {
2005 if (mode == MBEDTLS_AES_ENCRYPT) {
2006 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002007
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002008 memcpy(tmp, prv, 16);
2009 memcpy(prv, buf, 16);
2010 memcpy(buf, tmp, 16);
2011 }
2012
2013 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2014 if (ret != 0) {
2015 goto exit;
2016 }
2017
2018 }
2019
2020 if (memcmp(buf, aes_tests, 16) != 0) {
2021 ret = 1;
2022 goto exit;
2023 }
2024
2025 if (verbose != 0) {
2026 mbedtls_printf("passed\n");
2027 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002028 }
2029
Gilles Peskine449bd832023-01-11 14:50:10 +01002030 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002031 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002032 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002033 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002034#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002036#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002037 /*
2038 * CFB128 mode
2039 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002040 {
2041 static const int num_tests =
2042 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002043
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002044 for (i = 0; i < num_tests << 1; i++) {
2045 u = i >> 1;
2046 keybits = 128 + u * 64;
2047 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002048
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002049 if (verbose != 0) {
2050 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2051 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2052 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002053
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002054 memcpy(iv, aes_test_cfb128_iv, 16);
2055 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002056
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002057 offset = 0;
2058 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2059 /*
2060 * AES-192 is an optional feature that may be unavailable when
2061 * there is an alternative underlying implementation i.e. when
2062 * MBEDTLS_AES_ALT is defined.
2063 */
2064 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2065 mbedtls_printf("skipped\n");
2066 continue;
2067 } else if (ret != 0) {
2068 goto exit;
2069 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002070
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002071 if (mode == MBEDTLS_AES_DECRYPT) {
2072 memcpy(buf, aes_test_cfb128_ct[u], 64);
2073 aes_tests = aes_test_cfb128_pt;
2074 } else {
2075 memcpy(buf, aes_test_cfb128_pt, 64);
2076 aes_tests = aes_test_cfb128_ct[u];
2077 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002078
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002079 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2080 if (ret != 0) {
2081 goto exit;
2082 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002083
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002084 if (memcmp(buf, aes_tests, 64) != 0) {
2085 ret = 1;
2086 goto exit;
2087 }
2088
2089 if (verbose != 0) {
2090 mbedtls_printf("passed\n");
2091 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002092 }
2093
Gilles Peskine449bd832023-01-11 14:50:10 +01002094 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002095 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002096 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002097 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002098#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002099
Simon Butcherad4e4932018-04-29 00:43:47 +01002100#if defined(MBEDTLS_CIPHER_MODE_OFB)
2101 /*
2102 * OFB mode
2103 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002104 {
2105 static const int num_tests =
2106 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002107
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002108 for (i = 0; i < num_tests << 1; i++) {
2109 u = i >> 1;
2110 keybits = 128 + u * 64;
2111 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002112
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002113 if (verbose != 0) {
2114 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2115 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2116 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002117
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002118 memcpy(iv, aes_test_ofb_iv, 16);
2119 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002120
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002121 offset = 0;
2122 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2123 /*
2124 * AES-192 is an optional feature that may be unavailable when
2125 * there is an alternative underlying implementation i.e. when
2126 * MBEDTLS_AES_ALT is defined.
2127 */
2128 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2129 mbedtls_printf("skipped\n");
2130 continue;
2131 } else if (ret != 0) {
2132 goto exit;
2133 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002134
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002135 if (mode == MBEDTLS_AES_DECRYPT) {
2136 memcpy(buf, aes_test_ofb_ct[u], 64);
2137 aes_tests = aes_test_ofb_pt;
2138 } else {
2139 memcpy(buf, aes_test_ofb_pt, 64);
2140 aes_tests = aes_test_ofb_ct[u];
2141 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002142
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002143 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2144 if (ret != 0) {
2145 goto exit;
2146 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002147
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002148 if (memcmp(buf, aes_tests, 64) != 0) {
2149 ret = 1;
2150 goto exit;
2151 }
2152
2153 if (verbose != 0) {
2154 mbedtls_printf("passed\n");
2155 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002156 }
2157
Gilles Peskine449bd832023-01-11 14:50:10 +01002158 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002159 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002160 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002161 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002162#endif /* MBEDTLS_CIPHER_MODE_OFB */
2163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002164#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002165 /*
2166 * CTR mode
2167 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002168 {
2169 static const int num_tests =
2170 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002171
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002172 for (i = 0; i < num_tests << 1; i++) {
2173 u = i >> 1;
2174 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002175
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002176 if (verbose != 0) {
2177 mbedtls_printf(" AES-CTR-128 (%s): ",
2178 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2179 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002180
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002181 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2182 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002183
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002184 offset = 0;
2185 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2186 goto exit;
2187 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002188
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002189 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002190
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002191 if (mode == MBEDTLS_AES_DECRYPT) {
2192 memcpy(buf, aes_test_ctr_ct[u], len);
2193 aes_tests = aes_test_ctr_pt[u];
2194 } else {
2195 memcpy(buf, aes_test_ctr_pt[u], len);
2196 aes_tests = aes_test_ctr_ct[u];
2197 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002198
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002199 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2200 stream_block, buf, buf);
2201 if (ret != 0) {
2202 goto exit;
2203 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002204
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002205 if (memcmp(buf, aes_tests, len) != 0) {
2206 ret = 1;
2207 goto exit;
2208 }
2209
2210 if (verbose != 0) {
2211 mbedtls_printf("passed\n");
2212 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002213 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002214 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002215
Gilles Peskine449bd832023-01-11 14:50:10 +01002216 if (verbose != 0) {
2217 mbedtls_printf("\n");
2218 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002219#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002220
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002221#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002222 /*
2223 * XTS mode
2224 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002225 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002226 static const int num_tests =
2227 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2228 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002229
Gilles Peskine449bd832023-01-11 14:50:10 +01002230 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002231
Gilles Peskine449bd832023-01-11 14:50:10 +01002232 for (i = 0; i < num_tests << 1; i++) {
2233 const unsigned char *data_unit;
2234 u = i >> 1;
2235 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002236
Gilles Peskine449bd832023-01-11 14:50:10 +01002237 if (verbose != 0) {
2238 mbedtls_printf(" AES-XTS-128 (%s): ",
2239 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2240 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002241
Gilles Peskine449bd832023-01-11 14:50:10 +01002242 memset(key, 0, sizeof(key));
2243 memcpy(key, aes_test_xts_key[u], 32);
2244 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002245
Gilles Peskine449bd832023-01-11 14:50:10 +01002246 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002247
Gilles Peskine449bd832023-01-11 14:50:10 +01002248 if (mode == MBEDTLS_AES_DECRYPT) {
2249 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2250 if (ret != 0) {
2251 goto exit;
2252 }
2253 memcpy(buf, aes_test_xts_ct32[u], len);
2254 aes_tests = aes_test_xts_pt32[u];
2255 } else {
2256 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2257 if (ret != 0) {
2258 goto exit;
2259 }
2260 memcpy(buf, aes_test_xts_pt32[u], len);
2261 aes_tests = aes_test_xts_ct32[u];
2262 }
2263
2264
2265 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2266 buf, buf);
2267 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002268 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002269 }
2270
2271 if (memcmp(buf, aes_tests, len) != 0) {
2272 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002273 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002274 }
2275
2276 if (verbose != 0) {
2277 mbedtls_printf("passed\n");
2278 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002279 }
2280
Gilles Peskine449bd832023-01-11 14:50:10 +01002281 if (verbose != 0) {
2282 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002283 }
2284
Gilles Peskine449bd832023-01-11 14:50:10 +01002285 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002286 }
2287#endif /* MBEDTLS_CIPHER_MODE_XTS */
2288
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002289 ret = 0;
2290
2291exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002292 if (ret != 0 && verbose != 0) {
2293 mbedtls_printf("failed\n");
2294 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002295
Gilles Peskine449bd832023-01-11 14:50:10 +01002296 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002297
Gilles Peskine449bd832023-01-11 14:50:10 +01002298 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002299}
2300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002301#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002303#endif /* MBEDTLS_AES_C */