blob: 9dc7b7d148ff079477c62c6b34ece7840e827ae0 [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)
Gilles Peskine449bd832023-01-11 14:50:10 +01001067 if (mode == MBEDTLS_AES_ENCRYPT) {
1068 return mbedtls_internal_aes_encrypt(ctx, input, output);
1069 } else {
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001070#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang78ee0c92023-05-15 11:23:50 +08001072#else
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001073 return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
Jerry Yu29c91ba2023-08-04 11:02:04 +08001074#endif
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001075 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001076#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001077}
1078
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001080
Paul Bakker5121ce52009-01-03 21:22:43 +00001081/*
1082 * AES-CBC buffer encryption/decryption
1083 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001084int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1085 int mode,
1086 size_t length,
1087 unsigned char iv[16],
1088 const unsigned char *input,
1089 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001090{
Gilles Peskine7820a572021-07-07 21:08:28 +02001091 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001092 unsigned char temp[16];
1093
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001095 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001097
Paul Elliott2ad93672023-08-11 11:07:06 +01001098 /* Nothing to do if length is zero. */
1099 if (length == 0) {
1100 return 0;
1101 }
1102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 if (length % 16) {
1104 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1105 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001106
Jerry Yu9e628622023-08-17 11:20:09 +08001107#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 if (aes_padlock_ace > 0) {
1109 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1110 return 0;
1111 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001112
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001113 // If padlock data misaligned, we just fall back to
1114 // unaccelerated mode
1115 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001116 }
1117#endif
1118
Dave Rodgman906c63c2023-06-14 17:53:51 +01001119 const unsigned char *ivp = iv;
1120
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 if (mode == MBEDTLS_AES_DECRYPT) {
1122 while (length > 0) {
1123 memcpy(temp, input, 16);
1124 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1125 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001126 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001128 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001129 * the result for the next block in CBC, and the cost of transferring that data from
1130 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001131 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001134
1135 input += 16;
1136 output += 16;
1137 length -= 16;
1138 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 } else {
1140 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001141 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001142
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1144 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001145 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001147 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001148
1149 input += 16;
1150 output += 16;
1151 length -= 16;
1152 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001153 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001154 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001155 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001156
Gilles Peskine7820a572021-07-07 21:08:28 +02001157exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001159}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001160#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001161
Aorimn5f778012016-06-09 23:22:58 +02001162#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001163
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001164typedef unsigned char mbedtls_be128[16];
1165
1166/*
1167 * GF(2^128) multiplication function
1168 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001169 * This function multiplies a field element by x in the polynomial field
1170 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001171 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001172 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001173 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001174#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001175MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001176#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001177static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001178 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001179{
1180 uint64_t a, b, ra, rb;
1181
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 a = MBEDTLS_GET_UINT64_LE(x, 0);
1183 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001184
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1186 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001187
Gilles Peskine449bd832023-01-11 14:50:10 +01001188 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1189 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001190}
1191
Aorimn5f778012016-06-09 23:22:58 +02001192/*
1193 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001194 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001195 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001196 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001197 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001198#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001199MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001200#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001201int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1202 int mode,
1203 size_t length,
1204 const unsigned char data_unit[16],
1205 const unsigned char *input,
1206 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001207{
Janos Follath24eed8d2019-11-22 13:21:35 +00001208 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001209 size_t blocks = length / 16;
1210 size_t leftover = length % 16;
1211 unsigned char tweak[16];
1212 unsigned char prev_tweak[16];
1213 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001214
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001216 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001218
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001219 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 }
Aorimn5f778012016-06-09 23:22:58 +02001223
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001224 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001226 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 }
Aorimn5f778012016-06-09 23:22:58 +02001228
Jaeden Amerod82cd862018-04-28 15:02:45 +01001229 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001230 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1231 data_unit, tweak);
1232 if (ret != 0) {
1233 return ret;
1234 }
Aorimn5f778012016-06-09 23:22:58 +02001235
Gilles Peskine449bd832023-01-11 14:50:10 +01001236 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001237 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001238 /* We are on the last block in a decrypt operation that has
1239 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001240 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241 * the leftovers and then update the current tweak for use on this,
1242 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001243 memcpy(prev_tweak, tweak, sizeof(tweak));
1244 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001245 }
1246
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001248
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1250 if (ret != 0) {
1251 return ret;
1252 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001255
1256 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001258
1259 output += 16;
1260 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001261 }
1262
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001264 /* If we are on the leftover bytes in a decrypt operation, we need to
1265 * use the previous tweak for these bytes (as saved in prev_tweak). */
1266 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001267
Jaeden Amerod82cd862018-04-28 15:02:45 +01001268 /* We are now on the final part of the data unit, which doesn't divide
1269 * evenly by 16. It's time for ciphertext stealing. */
1270 size_t i;
1271 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001272
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001274 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001277 }
Aorimn5f778012016-06-09 23:22:58 +02001278
Dave Rodgman069e7f42022-11-24 19:37:26 +00001279 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001281
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282 /* Copy ciphertext bytes from the previous block for input in this
1283 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001285
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1287 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001288 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 }
Aorimn5f778012016-06-09 23:22:58 +02001290
Jaeden Amerod82cd862018-04-28 15:02:45 +01001291 /* Write the result back to the previous block, overriding the previous
1292 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001294 }
1295
Gilles Peskine449bd832023-01-11 14:50:10 +01001296 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001297}
1298#endif /* MBEDTLS_CIPHER_MODE_XTS */
1299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001300#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001301/*
1302 * AES-CFB128 buffer encryption/decryption
1303 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001304int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1305 int mode,
1306 size_t length,
1307 size_t *iv_off,
1308 unsigned char iv[16],
1309 const unsigned char *input,
1310 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001311{
Paul Bakker27fdf462011-06-09 13:55:13 +00001312 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001313 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001314 size_t n;
1315
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001317 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001319
1320 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001321
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 if (n > 15) {
1323 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1324 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001325
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 if (mode == MBEDTLS_AES_DECRYPT) {
1327 while (length--) {
1328 if (n == 0) {
1329 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1330 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001331 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001333 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001334
1335 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001336 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001337 iv[n] = (unsigned char) c;
1338
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001340 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 } else {
1342 while (length--) {
1343 if (n == 0) {
1344 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1345 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001346 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001348 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001349
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001351
Gilles Peskine449bd832023-01-11 14:50:10 +01001352 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001353 }
1354 }
1355
1356 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001357 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001358
Gilles Peskine7820a572021-07-07 21:08:28 +02001359exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001361}
Paul Bakker556efba2014-01-24 15:38:12 +01001362
1363/*
1364 * AES-CFB8 buffer encryption/decryption
1365 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001366int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1367 int mode,
1368 size_t length,
1369 unsigned char iv[16],
1370 const unsigned char *input,
1371 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001372{
Gilles Peskine7820a572021-07-07 21:08:28 +02001373 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001374 unsigned char c;
1375 unsigned char ov[17];
1376
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001378 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 }
1380 while (length--) {
1381 memcpy(ov, iv, 16);
1382 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1383 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001384 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 }
Paul Bakker556efba2014-01-24 15:38:12 +01001386
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001388 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 }
Paul Bakker556efba2014-01-24 15:38:12 +01001390
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001392
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001394 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001395 }
Paul Bakker556efba2014-01-24 15:38:12 +01001396
Gilles Peskine449bd832023-01-11 14:50:10 +01001397 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001398 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001399 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001400
Gilles Peskine7820a572021-07-07 21:08:28 +02001401exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001402 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001403}
Simon Butcher76a5b222018-04-22 22:57:27 +01001404#endif /* MBEDTLS_CIPHER_MODE_CFB */
1405
1406#if defined(MBEDTLS_CIPHER_MODE_OFB)
1407/*
1408 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1409 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001410int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1411 size_t length,
1412 size_t *iv_off,
1413 unsigned char iv[16],
1414 const unsigned char *input,
1415 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001416{
Simon Butcherad4e4932018-04-29 00:43:47 +01001417 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001418 size_t n;
1419
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001420 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001421
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 if (n > 15) {
1423 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1424 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001425
Gilles Peskine449bd832023-01-11 14:50:10 +01001426 while (length--) {
1427 if (n == 0) {
1428 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1429 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001430 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001431 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001432 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001433 *output++ = *input++ ^ iv[n];
1434
Gilles Peskine449bd832023-01-11 14:50:10 +01001435 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001436 }
1437
1438 *iv_off = n;
1439
Simon Butcherad4e4932018-04-29 00:43:47 +01001440exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001441 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001442}
1443#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001444
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001445#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001446/*
1447 * AES-CTR buffer encryption/decryption
1448 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001449int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1450 size_t length,
1451 size_t *nc_off,
1452 unsigned char nonce_counter[16],
1453 unsigned char stream_block[16],
1454 const unsigned char *input,
1455 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001456{
Paul Bakker369e14b2012-04-18 14:16:09 +00001457 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001458 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001459 size_t n;
1460
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001461 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001462
Gilles Peskine449bd832023-01-11 14:50:10 +01001463 if (n > 0x0F) {
1464 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1465 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001466
Gilles Peskine449bd832023-01-11 14:50:10 +01001467 while (length--) {
1468 if (n == 0) {
1469 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1470 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001471 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001472 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001473
Gilles Peskine449bd832023-01-11 14:50:10 +01001474 for (i = 16; i > 0; i--) {
1475 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001476 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001477 }
1478 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001479 }
1480 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001481 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001482
Gilles Peskine449bd832023-01-11 14:50:10 +01001483 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001484 }
1485
1486 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001487 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001488
Gilles Peskine7820a572021-07-07 21:08:28 +02001489exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001490 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001491}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001492#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001496#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001497/*
1498 * AES test vectors from:
1499 *
1500 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1501 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001502#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001503static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001504{
1505 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1506 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001507#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001508 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1509 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1510 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1511 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001512#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001513};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001514#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001515
Yanray Wang62c99912023-05-11 11:06:53 +08001516static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001517{
1518 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1519 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001520#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001521 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1522 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1523 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1524 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001525#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001526};
1527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001529static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001530{
1531 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1532 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001533#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001534 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1535 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1536 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1537 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001538#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001539};
1540
Yanray Wang62c99912023-05-11 11:06:53 +08001541static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001542{
1543 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1544 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001545#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001546 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1547 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1548 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1549 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001550#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001551};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001552#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001554#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001555/*
1556 * AES-CFB128 test vectors from:
1557 *
1558 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1559 */
Yanray Wang62c99912023-05-11 11:06:53 +08001560static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001561{
1562 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1563 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001564#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001565 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1566 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1567 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1568 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1569 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1570 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1571 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001572#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001573};
1574
1575static const unsigned char aes_test_cfb128_iv[16] =
1576{
1577 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1578 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1579};
1580
1581static const unsigned char aes_test_cfb128_pt[64] =
1582{
1583 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1584 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1585 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1586 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1587 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1588 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1589 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1590 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1591};
1592
Yanray Wang62c99912023-05-11 11:06:53 +08001593static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001594{
1595 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1596 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1597 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1598 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1599 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1600 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1601 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1602 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001603#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001604 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1605 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1606 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1607 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1608 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1609 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1610 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1611 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1612 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1613 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1614 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1615 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1616 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1617 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1618 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1619 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001620#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001621};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001622#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001623
Simon Butcherad4e4932018-04-29 00:43:47 +01001624#if defined(MBEDTLS_CIPHER_MODE_OFB)
1625/*
1626 * AES-OFB test vectors from:
1627 *
Simon Butcher5db13622018-06-04 22:11:25 +01001628 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001629 */
Yanray Wang62c99912023-05-11 11:06:53 +08001630static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001631{
1632 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1633 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001634#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001635 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1636 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1637 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1638 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1639 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1640 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1641 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001642#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001643};
1644
1645static const unsigned char aes_test_ofb_iv[16] =
1646{
1647 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1648 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1649};
1650
1651static const unsigned char aes_test_ofb_pt[64] =
1652{
1653 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1654 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1655 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1656 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1657 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1658 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1659 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1660 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1661};
1662
Yanray Wang62c99912023-05-11 11:06:53 +08001663static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001664{
1665 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1666 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1667 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1668 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1669 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1670 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1671 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1672 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001673#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001674 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1675 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1676 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1677 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1678 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1679 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1680 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1681 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1682 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1683 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1684 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1685 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1686 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1687 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1688 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1689 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001690#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001691};
1692#endif /* MBEDTLS_CIPHER_MODE_OFB */
1693
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001694#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001695/*
1696 * AES-CTR test vectors from:
1697 *
1698 * http://www.faqs.org/rfcs/rfc3686.html
1699 */
1700
Yanray Wang62c99912023-05-11 11:06:53 +08001701static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001702{
1703 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1704 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1705 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1706 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1707 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1708 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1709};
1710
Yanray Wang62c99912023-05-11 11:06:53 +08001711static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001712{
1713 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1715 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1716 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1717 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1718 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1719};
1720
Yanray Wang62c99912023-05-11 11:06:53 +08001721static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001722{
1723 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1724 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001725 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1726 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1727 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1728 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1729
1730 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1731 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1732 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1733 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1734 0x20, 0x21, 0x22, 0x23 }
1735};
1736
Yanray Wang62c99912023-05-11 11:06:53 +08001737static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001738{
1739 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1740 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1741 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1742 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1743 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1744 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1745 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1746 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1747 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1748 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1749 0x25, 0xB2, 0x07, 0x2F }
1750};
1751
1752static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001753{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001754#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001755
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001756#if defined(MBEDTLS_CIPHER_MODE_XTS)
1757/*
1758 * AES-XTS test vectors from:
1759 *
1760 * IEEE P1619/D16 Annex B
1761 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1762 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1763 */
1764static const unsigned char aes_test_xts_key[][32] =
1765{
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1770 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1771 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1772 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1773 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1774 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1775 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1776 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1777 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1778};
1779
1780static const unsigned char aes_test_xts_pt32[][32] =
1781{
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1794};
1795
1796static const unsigned char aes_test_xts_ct32[][32] =
1797{
1798 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1799 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1800 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1801 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1802 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1803 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1804 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1805 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1806 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1807 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1808 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1809 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1810};
1811
1812static const unsigned char aes_test_xts_data_unit[][16] =
1813{
Gilles Peskine449bd832023-01-11 14:50:10 +01001814 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1816 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1818 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001820};
1821
1822#endif /* MBEDTLS_CIPHER_MODE_XTS */
1823
Paul Bakker5121ce52009-01-03 21:22:43 +00001824/*
1825 * Checkup routine
1826 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001827int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001828{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001829 int ret = 0, i, j, u, mode;
1830 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001831 unsigned char key[32];
1832 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001833 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001834#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1835 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001836 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001837#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001838#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001839 unsigned char prv[16];
1840#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001841#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1842 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001843 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001844#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001845#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001846 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001847#endif
1848#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001849 unsigned char nonce_counter[16];
1850 unsigned char stream_block[16];
1851#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001852 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001853
Gilles Peskine449bd832023-01-11 14:50:10 +01001854 memset(key, 0, 32);
1855 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001856
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001857 if (verbose != 0) {
1858#if defined(MBEDTLS_AES_ALT)
1859 mbedtls_printf(" AES note: alternative implementation.\n");
1860#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001861#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001862#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001863 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001864#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001865 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001866#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001867#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001868#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001869 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1870 mbedtls_printf(" AES note: using AESNI.\n");
1871 } else
1872#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001873#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001874 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1875 mbedtls_printf(" AES note: using VIA Padlock.\n");
1876 } else
1877#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001878#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001879 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001880 mbedtls_printf(" AES note: using AESCE.\n");
1881 } else
1882#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001883 {
1884#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1885 mbedtls_printf(" AES note: built-in implementation.\n");
1886#endif
1887 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001888#endif /* MBEDTLS_AES_ALT */
1889 }
1890
Paul Bakker5121ce52009-01-03 21:22:43 +00001891 /*
1892 * ECB mode
1893 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001894 {
1895 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001896 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001897
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001898 for (i = 0; i < num_tests << 1; i++) {
1899 u = i >> 1;
1900 keybits = 128 + u * 64;
1901 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001902
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001903 if (verbose != 0) {
1904 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1905 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1906 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001907#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001908 if (mode == MBEDTLS_AES_DECRYPT) {
1909 if (verbose != 0) {
1910 mbedtls_printf("skipped\n");
1911 }
1912 continue;
1913 }
1914#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001915
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001916 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001917
Yanray Wangb67b4742023-10-31 17:10:32 +08001918#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001919 if (mode == MBEDTLS_AES_DECRYPT) {
1920 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1921 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001922 } else
1923#endif
1924 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001925 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1926 aes_tests = aes_test_ecb_enc[u];
1927 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001928
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001929 /*
1930 * AES-192 is an optional feature that may be unavailable when
1931 * there is an alternative underlying implementation i.e. when
1932 * MBEDTLS_AES_ALT is defined.
1933 */
1934 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1935 mbedtls_printf("skipped\n");
1936 continue;
1937 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001938 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001939 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001940
1941 for (j = 0; j < 10000; j++) {
1942 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1943 if (ret != 0) {
1944 goto exit;
1945 }
1946 }
1947
1948 if (memcmp(buf, aes_tests, 16) != 0) {
1949 ret = 1;
1950 goto exit;
1951 }
1952
1953 if (verbose != 0) {
1954 mbedtls_printf("passed\n");
1955 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001956 }
1957
Gilles Peskine449bd832023-01-11 14:50:10 +01001958 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001959 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001960 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001961 }
1962
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001963#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001964 /*
1965 * CBC mode
1966 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001967 {
1968 static const int num_tests =
1969 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001970
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001971 for (i = 0; i < num_tests << 1; i++) {
1972 u = i >> 1;
1973 keybits = 128 + u * 64;
1974 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001975
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001976 if (verbose != 0) {
1977 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1978 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001979 }
1980
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001981 memset(iv, 0, 16);
1982 memset(prv, 0, 16);
1983 memset(buf, 0, 16);
1984
1985 if (mode == MBEDTLS_AES_DECRYPT) {
1986 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1987 aes_tests = aes_test_cbc_dec[u];
1988 } else {
1989 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1990 aes_tests = aes_test_cbc_enc[u];
1991 }
1992
1993 /*
1994 * AES-192 is an optional feature that may be unavailable when
1995 * there is an alternative underlying implementation i.e. when
1996 * MBEDTLS_AES_ALT is defined.
1997 */
1998 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1999 mbedtls_printf("skipped\n");
2000 continue;
2001 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002002 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002003 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002004
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002005 for (j = 0; j < 10000; j++) {
2006 if (mode == MBEDTLS_AES_ENCRYPT) {
2007 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002008
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002009 memcpy(tmp, prv, 16);
2010 memcpy(prv, buf, 16);
2011 memcpy(buf, tmp, 16);
2012 }
2013
2014 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2015 if (ret != 0) {
2016 goto exit;
2017 }
2018
2019 }
2020
2021 if (memcmp(buf, aes_tests, 16) != 0) {
2022 ret = 1;
2023 goto exit;
2024 }
2025
2026 if (verbose != 0) {
2027 mbedtls_printf("passed\n");
2028 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002029 }
2030
Gilles Peskine449bd832023-01-11 14:50:10 +01002031 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002032 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002033 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002034 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002035#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002036
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002037#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 /*
2039 * CFB128 mode
2040 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002041 {
2042 static const int num_tests =
2043 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002044
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002045 for (i = 0; i < num_tests << 1; i++) {
2046 u = i >> 1;
2047 keybits = 128 + u * 64;
2048 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002049
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002050 if (verbose != 0) {
2051 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2052 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2053 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002054
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002055 memcpy(iv, aes_test_cfb128_iv, 16);
2056 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002057
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002058 offset = 0;
2059 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2060 /*
2061 * AES-192 is an optional feature that may be unavailable when
2062 * there is an alternative underlying implementation i.e. when
2063 * MBEDTLS_AES_ALT is defined.
2064 */
2065 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2066 mbedtls_printf("skipped\n");
2067 continue;
2068 } else if (ret != 0) {
2069 goto exit;
2070 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002071
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002072 if (mode == MBEDTLS_AES_DECRYPT) {
2073 memcpy(buf, aes_test_cfb128_ct[u], 64);
2074 aes_tests = aes_test_cfb128_pt;
2075 } else {
2076 memcpy(buf, aes_test_cfb128_pt, 64);
2077 aes_tests = aes_test_cfb128_ct[u];
2078 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002079
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002080 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2081 if (ret != 0) {
2082 goto exit;
2083 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002084
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002085 if (memcmp(buf, aes_tests, 64) != 0) {
2086 ret = 1;
2087 goto exit;
2088 }
2089
2090 if (verbose != 0) {
2091 mbedtls_printf("passed\n");
2092 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002093 }
2094
Gilles Peskine449bd832023-01-11 14:50:10 +01002095 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002097 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002098 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002099#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002100
Simon Butcherad4e4932018-04-29 00:43:47 +01002101#if defined(MBEDTLS_CIPHER_MODE_OFB)
2102 /*
2103 * OFB mode
2104 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002105 {
2106 static const int num_tests =
2107 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002108
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002109 for (i = 0; i < num_tests << 1; i++) {
2110 u = i >> 1;
2111 keybits = 128 + u * 64;
2112 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002113
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002114 if (verbose != 0) {
2115 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2116 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2117 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002118
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002119 memcpy(iv, aes_test_ofb_iv, 16);
2120 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002121
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002122 offset = 0;
2123 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2124 /*
2125 * AES-192 is an optional feature that may be unavailable when
2126 * there is an alternative underlying implementation i.e. when
2127 * MBEDTLS_AES_ALT is defined.
2128 */
2129 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2130 mbedtls_printf("skipped\n");
2131 continue;
2132 } else if (ret != 0) {
2133 goto exit;
2134 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002135
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002136 if (mode == MBEDTLS_AES_DECRYPT) {
2137 memcpy(buf, aes_test_ofb_ct[u], 64);
2138 aes_tests = aes_test_ofb_pt;
2139 } else {
2140 memcpy(buf, aes_test_ofb_pt, 64);
2141 aes_tests = aes_test_ofb_ct[u];
2142 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002143
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002144 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2145 if (ret != 0) {
2146 goto exit;
2147 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002148
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002149 if (memcmp(buf, aes_tests, 64) != 0) {
2150 ret = 1;
2151 goto exit;
2152 }
2153
2154 if (verbose != 0) {
2155 mbedtls_printf("passed\n");
2156 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002157 }
2158
Gilles Peskine449bd832023-01-11 14:50:10 +01002159 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002160 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002161 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002162 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002163#endif /* MBEDTLS_CIPHER_MODE_OFB */
2164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002165#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002166 /*
2167 * CTR mode
2168 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002169 {
2170 static const int num_tests =
2171 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002172
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002173 for (i = 0; i < num_tests << 1; i++) {
2174 u = i >> 1;
2175 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002176
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002177 if (verbose != 0) {
2178 mbedtls_printf(" AES-CTR-128 (%s): ",
2179 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2180 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002181
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002182 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2183 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002184
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002185 offset = 0;
2186 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2187 goto exit;
2188 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002189
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002190 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002191
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002192 if (mode == MBEDTLS_AES_DECRYPT) {
2193 memcpy(buf, aes_test_ctr_ct[u], len);
2194 aes_tests = aes_test_ctr_pt[u];
2195 } else {
2196 memcpy(buf, aes_test_ctr_pt[u], len);
2197 aes_tests = aes_test_ctr_ct[u];
2198 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002199
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002200 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2201 stream_block, buf, buf);
2202 if (ret != 0) {
2203 goto exit;
2204 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002205
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002206 if (memcmp(buf, aes_tests, len) != 0) {
2207 ret = 1;
2208 goto exit;
2209 }
2210
2211 if (verbose != 0) {
2212 mbedtls_printf("passed\n");
2213 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002214 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002215 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002216
Gilles Peskine449bd832023-01-11 14:50:10 +01002217 if (verbose != 0) {
2218 mbedtls_printf("\n");
2219 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002220#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002221
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002222#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002223 /*
2224 * XTS mode
2225 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002226 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002227 static const int num_tests =
2228 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2229 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002230
Gilles Peskine449bd832023-01-11 14:50:10 +01002231 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002232
Gilles Peskine449bd832023-01-11 14:50:10 +01002233 for (i = 0; i < num_tests << 1; i++) {
2234 const unsigned char *data_unit;
2235 u = i >> 1;
2236 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002237
Gilles Peskine449bd832023-01-11 14:50:10 +01002238 if (verbose != 0) {
2239 mbedtls_printf(" AES-XTS-128 (%s): ",
2240 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2241 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002242
Gilles Peskine449bd832023-01-11 14:50:10 +01002243 memset(key, 0, sizeof(key));
2244 memcpy(key, aes_test_xts_key[u], 32);
2245 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002248
Gilles Peskine449bd832023-01-11 14:50:10 +01002249 if (mode == MBEDTLS_AES_DECRYPT) {
2250 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2251 if (ret != 0) {
2252 goto exit;
2253 }
2254 memcpy(buf, aes_test_xts_ct32[u], len);
2255 aes_tests = aes_test_xts_pt32[u];
2256 } else {
2257 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2258 if (ret != 0) {
2259 goto exit;
2260 }
2261 memcpy(buf, aes_test_xts_pt32[u], len);
2262 aes_tests = aes_test_xts_ct32[u];
2263 }
2264
2265
2266 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2267 buf, buf);
2268 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002269 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002270 }
2271
2272 if (memcmp(buf, aes_tests, len) != 0) {
2273 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002274 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002275 }
2276
2277 if (verbose != 0) {
2278 mbedtls_printf("passed\n");
2279 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002280 }
2281
Gilles Peskine449bd832023-01-11 14:50:10 +01002282 if (verbose != 0) {
2283 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002284 }
2285
Gilles Peskine449bd832023-01-11 14:50:10 +01002286 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002287 }
2288#endif /* MBEDTLS_CIPHER_MODE_XTS */
2289
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002290 ret = 0;
2291
2292exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002293 if (ret != 0 && verbose != 0) {
2294 mbedtls_printf("failed\n");
2295 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002296
Gilles Peskine449bd832023-01-11 14:50:10 +01002297 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002298
Gilles Peskine449bd832023-01-11 14:50:10 +01002299 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002300}
2301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002302#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002303
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002304#endif /* MBEDTLS_AES_C */