blob: 377f8a8271009b60e0950ca6c5ea302a241f6329 [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 Wangdbcc0c62023-08-30 15:04:01 +080069#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
70 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY))
71#define MBEDTLS_AES_NEED_FORWARD_S_BOXES
72#endif
73
74#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) && \
75 !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
76#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 */
Yanray Wangdbcc0c62023-08-30 15:04:01 +080089#if defined(MBEDTLS_AES_NEED_FORWARD_S_BOXES)
Paul Bakker5121ce52009-01-03 21:22:43 +000090static const unsigned char FSb[256] =
91{
92 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
93 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
94 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
95 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
96 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
97 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
98 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
99 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
100 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
101 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
102 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
103 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
104 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
105 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
106 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
107 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
108 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
109 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
110 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
111 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
112 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
113 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
114 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
115 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
116 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
117 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
118 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
119 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
120 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
121 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
122 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
123 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
124};
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800125#endif /* MBEDTLS_AES_NEED_FORWARD_S_BOXES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000126
127/*
128 * Forward tables
129 */
130#define FT \
131\
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
133 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
134 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
135 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
136 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
137 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
138 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
139 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
140 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
141 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
142 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
143 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
144 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
145 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
146 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
147 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
148 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
149 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
150 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
151 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
152 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
153 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
154 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
155 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
156 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
157 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
158 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
159 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
160 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
161 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
162 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
163 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
164 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
165 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
166 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
167 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
168 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
169 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
170 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
171 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
172 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
173 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
174 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
175 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
176 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
177 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
178 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
179 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
180 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
181 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
182 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
183 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
184 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
185 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
186 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
187 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
188 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
189 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
190 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
191 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
192 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
193 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
194 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
195 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 +0000196
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100197#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100198#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000199static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000200#undef V
201
Hanno Beckerad049a92017-06-19 16:31:54 +0100202#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000205static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000206#undef V
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000209static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000210#undef V
211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000214#undef V
215
Hanno Becker177d3cf2017-06-07 15:52:48 +0100216#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200217
Yanray Wang422a77f2023-07-07 10:12:05 +0800218#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
Dave Rodgman1be24632023-06-29 12:01:24 +0100219
Paul Bakker5121ce52009-01-03 21:22:43 +0000220#undef FT
221
Yanray Wang78ee0c92023-05-15 11:23:50 +0800222#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000223/*
224 * Reverse S-box
225 */
226static const unsigned char RSb[256] =
227{
228 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
229 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
230 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
231 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
232 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
233 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
234 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
235 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
236 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
237 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
238 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
239 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
240 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
241 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
242 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
243 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
244 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
245 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
246 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
247 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
248 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
249 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
250 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
251 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
252 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
253 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
254 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
255 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
256 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
257 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
258 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
259 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
260};
Yanray Wang78ee0c92023-05-15 11:23:50 +0800261#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
263/*
264 * Reverse tables
265 */
266#define RT \
267\
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
269 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
270 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
271 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
272 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
273 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
274 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
275 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
276 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
277 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
278 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
279 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
280 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
281 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
282 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
283 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
284 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
285 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
286 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
287 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
288 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
289 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
290 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
291 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
292 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
293 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
294 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
295 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
296 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
297 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
298 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
299 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
300 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
301 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
302 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
303 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
304 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
305 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
306 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
307 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
308 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
309 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
310 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
311 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
312 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
313 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
314 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
315 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
316 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
317 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
318 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
319 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
320 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
321 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
322 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
323 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
324 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
325 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
326 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
327 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
328 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
329 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
330 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
331 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 +0000332
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800333#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000336static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000337#undef V
338
Hanno Beckerad049a92017-06-19 16:31:54 +0100339#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000342static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000343#undef V
344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000347#undef V
348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000350static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000351#undef V
352
Hanno Becker177d3cf2017-06-07 15:52:48 +0100353#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800354#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800355
Paul Bakker5121ce52009-01-03 21:22:43 +0000356#undef RT
357
Dave Rodgman34152a42023-06-27 18:31:24 +0100358#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000359/*
360 * Round constants
361 */
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200362static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000363{
364 0x00000001, 0x00000002, 0x00000004, 0x00000008,
365 0x00000010, 0x00000020, 0x00000040, 0x00000080,
366 0x0000001B, 0x00000036
367};
Yanray Wang422a77f2023-07-07 10:12:05 +0800368#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000369
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
372/*
373 * Forward S-box & tables
374 */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800375#if defined(MBEDTLS_AES_NEED_FORWARD_S_BOXES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000376static unsigned char FSb[256];
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800377#endif
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100378#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200379static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100380#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200381static uint32_t FT1[256];
382static uint32_t FT2[256];
383static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100384#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang422a77f2023-07-07 10:12:05 +0800385#endif /* !MBEDTLS_AES_ENCRYPT_ALT || !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000386
387/*
388 * Reverse S-box & tables
389 */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800390#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
391#if (!defined(MBEDTLS_AES_SETKEY_ENC_ALT) && !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) || \
392 !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000393static unsigned char RSb[256];
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800394#endif
395#endif /* !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100396
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800397#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000398static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100399#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000400static uint32_t RT1[256];
401static uint32_t RT2[256];
402static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100403#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800404#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Dave Rodgman8c753f92023-06-27 18:16:13 +0100406#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000407/*
408 * Round constants
409 */
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200410static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412/*
413 * Tables generation code
414 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100415#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
416#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
417#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
419static int aes_init_done = 0;
420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000422{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800423 int i;
424 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800425 uint8_t pow[256];
426 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
428 /*
429 * compute pow and log tables over GF(2^8)
430 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800433 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800434 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000435 }
436
437 /*
438 * calculate the round constants
439 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200441 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800442 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000443 }
444
445 /*
446 * generate the forward and reverse S-boxes
447 */
448 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800449#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800451#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000454 x = pow[255 - log[i]];
455
Yanray Wangfe944ce2023-06-26 18:16:01 +0800456 y = x; y = (y << 1) | (y >> 7);
457 x ^= y; y = (y << 1) | (y >> 7);
458 x ^= y; y = (y << 1) | (y >> 7);
459 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000460 x ^= y ^ 0x63;
461
Yanray Wangfe944ce2023-06-26 18:16:01 +0800462 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800463#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000464 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800465#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 }
467
468 /*
469 * generate the forward and reverse tables
470 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000472 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800473 y = XTIME(x);
474 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 FT0[i] = ((uint32_t) y) ^
477 ((uint32_t) x << 8) ^
478 ((uint32_t) x << 16) ^
479 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
Hanno Beckerad049a92017-06-19 16:31:54 +0100481#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 FT1[i] = ROTL8(FT0[i]);
483 FT2[i] = ROTL8(FT1[i]);
484 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100485#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800487#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000488 x = RSb[i];
489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
491 ((uint32_t) MUL(0x09, x) << 8) ^
492 ((uint32_t) MUL(0x0D, x) << 16) ^
493 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
Hanno Beckerad049a92017-06-19 16:31:54 +0100495#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 RT1[i] = ROTL8(RT0[i]);
497 RT2[i] = ROTL8(RT1[i]);
498 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100499#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800500#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000501 }
502}
503
Yanray Wang422a77f2023-07-07 10:12:05 +0800504#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Dave Rodgman8c753f92023-06-27 18:16:13 +0100505
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200506#undef ROTL8
507
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
Hanno Beckerad049a92017-06-19 16:31:54 +0100510#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
513#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
514#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200515
516#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100517#define AES_RT1(idx) ROTL8(RT0[idx])
518#define AES_RT2(idx) ROTL16(RT0[idx])
519#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200520
521#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100522#define AES_FT1(idx) ROTL8(FT0[idx])
523#define AES_FT2(idx) ROTL16(FT0[idx])
524#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200525
Hanno Becker177d3cf2017-06-07 15:52:48 +0100526#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200527
528#define AES_RT0(idx) RT0[idx]
529#define AES_RT1(idx) RT1[idx]
530#define AES_RT2(idx) RT2[idx]
531#define AES_RT3(idx) RT3[idx]
532
533#define AES_FT0(idx) FT0[idx]
534#define AES_FT1(idx) FT1[idx]
535#define AES_FT2(idx) FT2[idx]
536#define AES_FT3(idx) FT3[idx]
537
Hanno Becker177d3cf2017-06-07 15:52:48 +0100538#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200539
Gilles Peskine449bd832023-01-11 14:50:10 +0100540void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200541{
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200543}
544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200546{
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200548 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200552}
553
Jaeden Amero9366feb2018-05-29 18:55:17 +0100554#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100555void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100556{
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 mbedtls_aes_init(&ctx->crypt);
558 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100559}
560
Gilles Peskine449bd832023-01-11 14:50:10 +0100561void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100562{
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100564 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 }
Simon Butcher5201e412018-12-06 17:40:14 +0000566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 mbedtls_aes_free(&ctx->crypt);
568 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100569}
570#endif /* MBEDTLS_CIPHER_MODE_XTS */
571
Gilles Peskine0de8f852023-03-16 17:14:59 +0100572/* Some implementations need the round keys to be aligned.
573 * Return an offset to be added to buf, such that (buf + offset) is
574 * correctly aligned.
575 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
576 * i.e. an offset of 1 means 4 bytes and so on.
577 */
Jerry Yu96084472023-08-17 18:10:45 +0800578#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100579 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100580#define MAY_NEED_TO_ALIGN
581#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100582
Yanray Wang78ee0c92023-05-15 11:23:50 +0800583#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
584 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY))
Gilles Peskine0de8f852023-03-16 17:14:59 +0100585static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
586{
587#if defined(MAY_NEED_TO_ALIGN)
588 int align_16_bytes = 0;
589
Jerry Yu9e628622023-08-17 11:20:09 +0800590#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100591 if (aes_padlock_ace == -1) {
592 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
593 }
594 if (aes_padlock_ace) {
595 align_16_bytes = 1;
596 }
597#endif
598
Gilles Peskine9c682e72023-03-16 17:21:33 +0100599#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100600 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
601 align_16_bytes = 1;
602 }
603#endif
604
605 if (align_16_bytes) {
606 /* These implementations needs 16-byte alignment
607 * for the round key array. */
608 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
609 if (delta == 0) {
610 return 0;
611 } else {
612 return 4 - delta; // 16 bytes = 4 uint32_t
613 }
614 }
615#else /* MAY_NEED_TO_ALIGN */
616 (void) buf;
617#endif /* MAY_NEED_TO_ALIGN */
618
619 return 0;
620}
Yanray Wang78ee0c92023-05-15 11:23:50 +0800621#endif /* MAY_NEED_TO_ALIGN || !MBEDTLS_AES_SETKEY_ENC_ALT ||
622 (!MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100623
Paul Bakker5121ce52009-01-03 21:22:43 +0000624/*
625 * AES key schedule (encryption)
626 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200627#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100628int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
629 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000630{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000631 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800635#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 case 192: ctx->nr = 12; break;
637 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800638#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 }
641
Simon Butcher5201e412018-12-06 17:40:14 +0000642#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000644 aes_gen_tables();
645 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000646 }
647#endif
648
Gilles Peskine0de8f852023-03-16 17:14:59 +0100649 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100650 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100652#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
654 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
655 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100656#endif
657
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800658#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100659 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800660 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
661 }
662#endif
663
Jerry Yu29c91ba2023-08-04 11:02:04 +0800664#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800665 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 }
668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 case 10:
671
Jerry Yu3a0f0442023-08-17 17:06:21 +0800672 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200673 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
675 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
676 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
677 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
679 RK[5] = RK[1] ^ RK[4];
680 RK[6] = RK[2] ^ RK[5];
681 RK[7] = RK[3] ^ RK[6];
682 }
683 break;
684
Arto Kinnunen732ca322023-04-14 14:26:10 +0800685#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000686 case 12:
687
Jerry Yu3a0f0442023-08-17 17:06:21 +0800688 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200689 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
691 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
692 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
693 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
695 RK[7] = RK[1] ^ RK[6];
696 RK[8] = RK[2] ^ RK[7];
697 RK[9] = RK[3] ^ RK[8];
698 RK[10] = RK[4] ^ RK[9];
699 RK[11] = RK[5] ^ RK[10];
700 }
701 break;
702
703 case 14:
704
Jerry Yu3a0f0442023-08-17 17:06:21 +0800705 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200706 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
708 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
709 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
710 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
712 RK[9] = RK[1] ^ RK[8];
713 RK[10] = RK[2] ^ RK[9];
714 RK[11] = RK[3] ^ RK[10];
715
716 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
718 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
719 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
720 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000721
722 RK[13] = RK[5] ^ RK[12];
723 RK[14] = RK[6] ^ RK[13];
724 RK[15] = RK[7] ^ RK[14];
725 }
726 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800727#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000728 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000729
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800731#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000732}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200733#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000734
735/*
736 * AES key schedule (decryption)
737 */
Yanray Wang78ee0c92023-05-15 11:23:50 +0800738#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100739int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
740 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000741{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800742#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800743 uint32_t *SK;
744#endif
745 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200746 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000747 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800748
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
Gilles Peskine0de8f852023-03-16 17:14:59 +0100752 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100753 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000754
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200755 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200757 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000759
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200760 ctx->nr = cty.nr;
761
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100762#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
764 mbedtls_aesni_inverse_key((unsigned char *) RK,
765 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200766 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100767 }
768#endif
769
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800770#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100771 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800772 mbedtls_aesce_inverse_key(
773 (unsigned char *) RK,
774 (const unsigned char *) (cty.buf + cty.rk_offset),
775 ctx->nr);
776 goto exit;
777 }
778#endif
779
Jerry Yu29c91ba2023-08-04 11:02:04 +0800780#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100781 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000782
783 *RK++ = *SK++;
784 *RK++ = *SK++;
785 *RK++ = *SK++;
786 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800787 SK -= 8;
788 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
789 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
791 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
792 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
793 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 }
795 }
796
797 *RK++ = *SK++;
798 *RK++ = *SK++;
799 *RK++ = *SK++;
800 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800801#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200802exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000806}
Yanray Wang78ee0c92023-05-15 11:23:50 +0800807#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808
809#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100810static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
811 unsigned int keybits,
812 const unsigned char **key1,
813 unsigned int *key1bits,
814 const unsigned char **key2,
815 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100816{
817 const unsigned int half_keybits = keybits / 2;
818 const unsigned int half_keybytes = half_keybits / 8;
819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100821 case 256: break;
822 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100824 }
825
826 *key1bits = half_keybits;
827 *key2bits = half_keybits;
828 *key1 = &key[0];
829 *key2 = &key[half_keybytes];
830
831 return 0;
832}
833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
835 const unsigned char *key,
836 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100837{
Janos Follath24eed8d2019-11-22 13:21:35 +0000838 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100839 const unsigned char *key1, *key2;
840 unsigned int key1bits, key2bits;
841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
843 &key2, &key2bits);
844 if (ret != 0) {
845 return ret;
846 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100847
848 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
850 if (ret != 0) {
851 return ret;
852 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100853
854 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100856}
857
Gilles Peskine449bd832023-01-11 14:50:10 +0100858int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
859 const unsigned char *key,
860 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100861{
Janos Follath24eed8d2019-11-22 13:21:35 +0000862 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100863 const unsigned char *key1, *key2;
864 unsigned int key1bits, key2bits;
865
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
867 &key2, &key2bits);
868 if (ret != 0) {
869 return ret;
870 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100871
872 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
874 if (ret != 0) {
875 return ret;
876 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100877
878 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100880}
881#endif /* MBEDTLS_CIPHER_MODE_XTS */
882
Gilles Peskine449bd832023-01-11 14:50:10 +0100883#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100884 do \
885 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
887 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
888 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
889 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100890 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
892 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
893 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
894 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100895 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
897 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
898 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
899 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100900 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
902 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
903 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
904 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
905 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100908 do \
909 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
911 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
912 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
913 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100914 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
916 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
917 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
918 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100919 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
921 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
922 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
923 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100924 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
926 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
927 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
928 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
929 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000930
931/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200932 * AES-ECB block encryption
933 */
934#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100935int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
936 const unsigned char input[16],
937 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200938{
939 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100940 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200942 uint32_t X[4];
943 uint32_t Y[4];
944 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
947 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
948 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
949 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
952 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]);
953 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 +0200954 }
955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 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 +0200957
Gilles Peskine5197c662020-08-26 17:03:24 +0200958 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
960 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
961 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200963
Gilles Peskine5197c662020-08-26 17:03:24 +0200964 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
966 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
967 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200969
Gilles Peskine5197c662020-08-26 17:03:24 +0200970 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
972 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
973 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
974 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200975
Gilles Peskine5197c662020-08-26 17:03:24 +0200976 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
978 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
979 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
980 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
983 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
984 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
985 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000986
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500988
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200990}
991#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
992
993/*
994 * AES-ECB block decryption
995 */
Yanray Wang78ee0c92023-05-15 11:23:50 +0800996#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100997int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
998 const unsigned char input[16],
999 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001000{
1001 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +01001002 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001004 uint32_t X[4];
1005 uint32_t Y[4];
1006 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1009 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1010 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1011 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001012
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1014 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]);
1015 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 +02001016 }
1017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 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 +02001019
Gilles Peskine5197c662020-08-26 17:03:24 +02001020 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1022 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1023 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001025
Gilles Peskine5197c662020-08-26 17:03:24 +02001026 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1028 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1029 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001031
Gilles Peskine5197c662020-08-26 17:03:24 +02001032 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1034 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1035 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1036 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001037
Gilles Peskine5197c662020-08-26 17:03:24 +02001038 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1040 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1041 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1042 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001043
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1045 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1046 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1047 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001048
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001050
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001052}
Yanray Wang78ee0c92023-05-15 11:23:50 +08001053#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001054
Gilles Peskine0de8f852023-03-16 17:14:59 +01001055#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001056/* VIA Padlock and our intrinsics-based implementation of AESNI require
1057 * the round keys to be aligned on a 16-byte boundary. We take care of this
1058 * before creating them, but the AES context may have moved (this can happen
1059 * if the library is called from a language with managed memory), and in later
1060 * calls it might have a different alignment with respect to 16-byte memory.
1061 * So we may need to realign.
1062 */
1063static void aes_maybe_realign(mbedtls_aes_context *ctx)
1064{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001065 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1066 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001067 memmove(ctx->buf + new_offset, // new address
1068 ctx->buf + ctx->rk_offset, // current address
1069 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1070 ctx->rk_offset = new_offset;
1071 }
1072}
1073#endif
1074
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001075/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001076 * AES-ECB block encryption/decryption
1077 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001078int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1079 int mode,
1080 const unsigned char input[16],
1081 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001082{
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001084 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001086
Gilles Peskine0de8f852023-03-16 17:14:59 +01001087#if defined(MAY_NEED_TO_ALIGN)
1088 aes_maybe_realign(ctx);
1089#endif
1090
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001091#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1093 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1094 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001095#endif
1096
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001097#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001098 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001099 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1100 }
1101#endif
1102
Jerry Yu9e628622023-08-17 11:20:09 +08001103#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001104 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001105 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001106 }
1107#endif
1108
Jerry Yu29c91ba2023-08-04 11:02:04 +08001109#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001110#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001111 if (mode == MBEDTLS_AES_ENCRYPT) {
1112 return mbedtls_internal_aes_encrypt(ctx, input, output);
1113 } else {
1114 return mbedtls_internal_aes_decrypt(ctx, input, output);
1115 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001116#else
1117 return mbedtls_internal_aes_encrypt(ctx, input, output);
Jerry Yu29c91ba2023-08-04 11:02:04 +08001118#endif
Yanray Wang78ee0c92023-05-15 11:23:50 +08001119#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001120}
1121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001122#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001123
Paul Bakker5121ce52009-01-03 21:22:43 +00001124/*
1125 * AES-CBC buffer encryption/decryption
1126 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001127int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1128 int mode,
1129 size_t length,
1130 unsigned char iv[16],
1131 const unsigned char *input,
1132 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001133{
Gilles Peskine7820a572021-07-07 21:08:28 +02001134 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001135 unsigned char temp[16];
1136
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001138 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001140
Paul Elliott2ad93672023-08-11 11:07:06 +01001141 /* Nothing to do if length is zero. */
1142 if (length == 0) {
1143 return 0;
1144 }
1145
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 if (length % 16) {
1147 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1148 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001149
Jerry Yu9e628622023-08-17 11:20:09 +08001150#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 if (aes_padlock_ace > 0) {
1152 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1153 return 0;
1154 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001155
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001156 // If padlock data misaligned, we just fall back to
1157 // unaccelerated mode
1158 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001159 }
1160#endif
1161
Dave Rodgman906c63c2023-06-14 17:53:51 +01001162 const unsigned char *ivp = iv;
1163
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 if (mode == MBEDTLS_AES_DECRYPT) {
1165 while (length > 0) {
1166 memcpy(temp, input, 16);
1167 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1168 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001169 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001171 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001172 * the result for the next block in CBC, and the cost of transferring that data from
1173 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001174 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001177
1178 input += 16;
1179 output += 16;
1180 length -= 16;
1181 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 } else {
1183 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001184 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001185
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1187 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001188 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001190 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001191
1192 input += 16;
1193 output += 16;
1194 length -= 16;
1195 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001196 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001197 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001198 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001199
Gilles Peskine7820a572021-07-07 21:08:28 +02001200exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001201 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001202}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001203#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001204
Aorimn5f778012016-06-09 23:22:58 +02001205#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001206
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001207typedef unsigned char mbedtls_be128[16];
1208
1209/*
1210 * GF(2^128) multiplication function
1211 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001212 * This function multiplies a field element by x in the polynomial field
1213 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001214 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001215 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001216 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001217#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001218MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001219#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001220static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001221 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001222{
1223 uint64_t a, b, ra, rb;
1224
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 a = MBEDTLS_GET_UINT64_LE(x, 0);
1226 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001227
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1229 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001230
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1232 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001233}
1234
Aorimn5f778012016-06-09 23:22:58 +02001235/*
1236 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001237 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001238 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001239 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001240 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001241#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001242MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001243#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001244int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1245 int mode,
1246 size_t length,
1247 const unsigned char data_unit[16],
1248 const unsigned char *input,
1249 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001250{
Janos Follath24eed8d2019-11-22 13:21:35 +00001251 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252 size_t blocks = length / 16;
1253 size_t leftover = length % 16;
1254 unsigned char tweak[16];
1255 unsigned char prev_tweak[16];
1256 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001257
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001259 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001261
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001262 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001264 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 }
Aorimn5f778012016-06-09 23:22:58 +02001266
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001267 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001269 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001270 }
Aorimn5f778012016-06-09 23:22:58 +02001271
Jaeden Amerod82cd862018-04-28 15:02:45 +01001272 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1274 data_unit, tweak);
1275 if (ret != 0) {
1276 return ret;
1277 }
Aorimn5f778012016-06-09 23:22:58 +02001278
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001280 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281 /* We are on the last block in a decrypt operation that has
1282 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001283 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001284 * the leftovers and then update the current tweak for use on this,
1285 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 memcpy(prev_tweak, tweak, sizeof(tweak));
1287 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001288 }
1289
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001291
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1293 if (ret != 0) {
1294 return ret;
1295 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001296
Gilles Peskine449bd832023-01-11 14:50:10 +01001297 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001298
1299 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001300 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001301
1302 output += 16;
1303 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001304 }
1305
Gilles Peskine449bd832023-01-11 14:50:10 +01001306 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001307 /* If we are on the leftover bytes in a decrypt operation, we need to
1308 * use the previous tweak for these bytes (as saved in prev_tweak). */
1309 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001310
Jaeden Amerod82cd862018-04-28 15:02:45 +01001311 /* We are now on the final part of the data unit, which doesn't divide
1312 * evenly by 16. It's time for ciphertext stealing. */
1313 size_t i;
1314 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001315
Jaeden Amerod82cd862018-04-28 15:02:45 +01001316 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001317 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001319 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001320 }
Aorimn5f778012016-06-09 23:22:58 +02001321
Dave Rodgman069e7f42022-11-24 19:37:26 +00001322 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001324
Jaeden Amerod82cd862018-04-28 15:02:45 +01001325 /* Copy ciphertext bytes from the previous block for input in this
1326 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001328
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1330 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001331 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 }
Aorimn5f778012016-06-09 23:22:58 +02001333
Jaeden Amerod82cd862018-04-28 15:02:45 +01001334 /* Write the result back to the previous block, overriding the previous
1335 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001336 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001337 }
1338
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001340}
1341#endif /* MBEDTLS_CIPHER_MODE_XTS */
1342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001343#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001344/*
1345 * AES-CFB128 buffer encryption/decryption
1346 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001347int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1348 int mode,
1349 size_t length,
1350 size_t *iv_off,
1351 unsigned char iv[16],
1352 const unsigned char *input,
1353 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001354{
Paul Bakker27fdf462011-06-09 13:55:13 +00001355 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001356 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001357 size_t n;
1358
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001360 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001361 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001362
1363 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001364
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 if (n > 15) {
1366 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1367 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001368
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 if (mode == MBEDTLS_AES_DECRYPT) {
1370 while (length--) {
1371 if (n == 0) {
1372 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1373 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001374 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001375 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001376 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001377
1378 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001380 iv[n] = (unsigned char) c;
1381
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001383 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 } else {
1385 while (length--) {
1386 if (n == 0) {
1387 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1388 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001389 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001390 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001391 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001392
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001394
Gilles Peskine449bd832023-01-11 14:50:10 +01001395 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001396 }
1397 }
1398
1399 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001400 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001401
Gilles Peskine7820a572021-07-07 21:08:28 +02001402exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001403 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001404}
Paul Bakker556efba2014-01-24 15:38:12 +01001405
1406/*
1407 * AES-CFB8 buffer encryption/decryption
1408 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001409int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1410 int mode,
1411 size_t length,
1412 unsigned char iv[16],
1413 const unsigned char *input,
1414 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001415{
Gilles Peskine7820a572021-07-07 21:08:28 +02001416 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001417 unsigned char c;
1418 unsigned char ov[17];
1419
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001421 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 }
1423 while (length--) {
1424 memcpy(ov, iv, 16);
1425 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1426 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001427 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001428 }
Paul Bakker556efba2014-01-24 15:38:12 +01001429
Gilles Peskine449bd832023-01-11 14:50:10 +01001430 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001431 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001432 }
Paul Bakker556efba2014-01-24 15:38:12 +01001433
Gilles Peskine449bd832023-01-11 14:50:10 +01001434 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001435
Gilles Peskine449bd832023-01-11 14:50:10 +01001436 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001437 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001438 }
Paul Bakker556efba2014-01-24 15:38:12 +01001439
Gilles Peskine449bd832023-01-11 14:50:10 +01001440 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001441 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001442 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001443
Gilles Peskine7820a572021-07-07 21:08:28 +02001444exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001445 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001446}
Simon Butcher76a5b222018-04-22 22:57:27 +01001447#endif /* MBEDTLS_CIPHER_MODE_CFB */
1448
1449#if defined(MBEDTLS_CIPHER_MODE_OFB)
1450/*
1451 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1452 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001453int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1454 size_t length,
1455 size_t *iv_off,
1456 unsigned char iv[16],
1457 const unsigned char *input,
1458 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001459{
Simon Butcherad4e4932018-04-29 00:43:47 +01001460 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001461 size_t n;
1462
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001463 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001464
Gilles Peskine449bd832023-01-11 14:50:10 +01001465 if (n > 15) {
1466 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1467 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001468
Gilles Peskine449bd832023-01-11 14:50:10 +01001469 while (length--) {
1470 if (n == 0) {
1471 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1472 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001473 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001474 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001475 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001476 *output++ = *input++ ^ iv[n];
1477
Gilles Peskine449bd832023-01-11 14:50:10 +01001478 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001479 }
1480
1481 *iv_off = n;
1482
Simon Butcherad4e4932018-04-29 00:43:47 +01001483exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001484 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001485}
1486#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001488#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489/*
1490 * AES-CTR buffer encryption/decryption
1491 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001492int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1493 size_t length,
1494 size_t *nc_off,
1495 unsigned char nonce_counter[16],
1496 unsigned char stream_block[16],
1497 const unsigned char *input,
1498 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001499{
Paul Bakker369e14b2012-04-18 14:16:09 +00001500 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001501 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001502 size_t n;
1503
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001504 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001505
Gilles Peskine449bd832023-01-11 14:50:10 +01001506 if (n > 0x0F) {
1507 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1508 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001509
Gilles Peskine449bd832023-01-11 14:50:10 +01001510 while (length--) {
1511 if (n == 0) {
1512 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1513 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001514 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001515 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001516
Gilles Peskine449bd832023-01-11 14:50:10 +01001517 for (i = 16; i > 0; i--) {
1518 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001519 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001520 }
1521 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001522 }
1523 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001524 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001525
Gilles Peskine449bd832023-01-11 14:50:10 +01001526 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001527 }
1528
1529 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001530 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001531
Gilles Peskine7820a572021-07-07 21:08:28 +02001532exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001533 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001534}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001535#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001536
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001537#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001538
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001539#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001540/*
1541 * AES test vectors from:
1542 *
1543 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1544 */
Yanray Wang78ee0c92023-05-15 11:23:50 +08001545#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Yanray Wang62c99912023-05-11 11:06:53 +08001546static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001547{
1548 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1549 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001550#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001551 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1552 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1553 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1554 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001555#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001556};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001557#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001558
Yanray Wang62c99912023-05-11 11:06:53 +08001559static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001560{
1561 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1562 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001563#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001564 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1565 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1566 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1567 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001568#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001569};
1570
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001571#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001572static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001573{
1574 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1575 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001576#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001577 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1578 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1579 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1580 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001581#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001582};
1583
Yanray Wang62c99912023-05-11 11:06:53 +08001584static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001585{
1586 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1587 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001588#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001589 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1590 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1591 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1592 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001593#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001594};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001595#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001596
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001597#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001598/*
1599 * AES-CFB128 test vectors from:
1600 *
1601 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1602 */
Yanray Wang62c99912023-05-11 11:06:53 +08001603static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001604{
1605 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1606 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001607#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001608 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1609 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1610 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1611 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1612 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1613 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1614 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001615#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001616};
1617
1618static const unsigned char aes_test_cfb128_iv[16] =
1619{
1620 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1621 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1622};
1623
1624static const unsigned char aes_test_cfb128_pt[64] =
1625{
1626 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1627 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1628 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1629 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1630 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1631 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1632 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1633 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1634};
1635
Yanray Wang62c99912023-05-11 11:06:53 +08001636static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001637{
1638 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1639 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1640 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1641 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1642 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1643 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1644 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1645 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001646#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001647 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1648 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1649 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1650 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1651 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1652 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1653 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1654 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1655 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1656 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1657 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1658 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1659 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1660 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1661 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1662 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001663#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001664};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001665#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001666
Simon Butcherad4e4932018-04-29 00:43:47 +01001667#if defined(MBEDTLS_CIPHER_MODE_OFB)
1668/*
1669 * AES-OFB test vectors from:
1670 *
Simon Butcher5db13622018-06-04 22:11:25 +01001671 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001672 */
Yanray Wang62c99912023-05-11 11:06:53 +08001673static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001674{
1675 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1676 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001677#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001678 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1679 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1680 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1681 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1682 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1683 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1684 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001685#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001686};
1687
1688static const unsigned char aes_test_ofb_iv[16] =
1689{
1690 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1691 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1692};
1693
1694static const unsigned char aes_test_ofb_pt[64] =
1695{
1696 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1697 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1698 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1699 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1700 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1701 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1702 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1703 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1704};
1705
Yanray Wang62c99912023-05-11 11:06:53 +08001706static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001707{
1708 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1709 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1710 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1711 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1712 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1713 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1714 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1715 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001716#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001717 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1718 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1719 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1720 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1721 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1722 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1723 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1724 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1725 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1726 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1727 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1728 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1729 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1730 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1731 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1732 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001733#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001734};
1735#endif /* MBEDTLS_CIPHER_MODE_OFB */
1736
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001737#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001738/*
1739 * AES-CTR test vectors from:
1740 *
1741 * http://www.faqs.org/rfcs/rfc3686.html
1742 */
1743
Yanray Wang62c99912023-05-11 11:06:53 +08001744static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001745{
1746 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1747 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1748 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1749 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1750 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1751 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1752};
1753
Yanray Wang62c99912023-05-11 11:06:53 +08001754static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001755{
1756 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1758 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1759 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1760 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1761 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1762};
1763
Yanray Wang62c99912023-05-11 11:06:53 +08001764static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001765{
1766 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1767 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001768 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1769 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1770 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1771 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1772
1773 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1774 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1775 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1776 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1777 0x20, 0x21, 0x22, 0x23 }
1778};
1779
Yanray Wang62c99912023-05-11 11:06:53 +08001780static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001781{
1782 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1783 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1784 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1785 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1786 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1787 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1788 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1789 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1790 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1791 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1792 0x25, 0xB2, 0x07, 0x2F }
1793};
1794
1795static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001796{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001797#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001798
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001799#if defined(MBEDTLS_CIPHER_MODE_XTS)
1800/*
1801 * AES-XTS test vectors from:
1802 *
1803 * IEEE P1619/D16 Annex B
1804 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1805 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1806 */
1807static const unsigned char aes_test_xts_key[][32] =
1808{
1809 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1813 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1814 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1815 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1816 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1817 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1818 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1819 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1820 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1821};
1822
1823static const unsigned char aes_test_xts_pt32[][32] =
1824{
1825 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1829 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1830 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1831 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1832 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1833 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1834 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1835 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1836 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1837};
1838
1839static const unsigned char aes_test_xts_ct32[][32] =
1840{
1841 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1842 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1843 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1844 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1845 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1846 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1847 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1848 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1849 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1850 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1851 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1852 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1853};
1854
1855static const unsigned char aes_test_xts_data_unit[][16] =
1856{
Gilles Peskine449bd832023-01-11 14:50:10 +01001857 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1859 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1861 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001863};
1864
1865#endif /* MBEDTLS_CIPHER_MODE_XTS */
1866
Paul Bakker5121ce52009-01-03 21:22:43 +00001867/*
1868 * Checkup routine
1869 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001870int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001871{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001872 int ret = 0, i, j, u, mode;
1873 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001874 unsigned char key[32];
1875 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001876 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001877#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1878 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001879 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001880#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001881#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001882 unsigned char prv[16];
1883#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001884#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1885 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001886 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001887#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001888#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001889 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001890#endif
1891#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001892 unsigned char nonce_counter[16];
1893 unsigned char stream_block[16];
1894#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001895 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
Gilles Peskine449bd832023-01-11 14:50:10 +01001897 memset(key, 0, 32);
1898 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001899
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001900 if (verbose != 0) {
1901#if defined(MBEDTLS_AES_ALT)
1902 mbedtls_printf(" AES note: alternative implementation.\n");
1903#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001904#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001905#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001906 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001907#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001908 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001909#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001910#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001911#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001912 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1913 mbedtls_printf(" AES note: using AESNI.\n");
1914 } else
1915#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001916#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001917 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1918 mbedtls_printf(" AES note: using VIA Padlock.\n");
1919 } else
1920#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001921#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001922 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001923 mbedtls_printf(" AES note: using AESCE.\n");
1924 } else
1925#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001926 {
1927#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1928 mbedtls_printf(" AES note: built-in implementation.\n");
1929#endif
1930 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001931#endif /* MBEDTLS_AES_ALT */
1932 }
1933
Paul Bakker5121ce52009-01-03 21:22:43 +00001934 /*
1935 * ECB mode
1936 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001937 {
1938 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001939 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001941 for (i = 0; i < num_tests << 1; i++) {
1942 u = i >> 1;
1943 keybits = 128 + u * 64;
1944 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001945
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001946 if (verbose != 0) {
1947 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1948 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1949 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001950#if defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
1951 if (mode == MBEDTLS_AES_DECRYPT) {
1952 if (verbose != 0) {
1953 mbedtls_printf("skipped\n");
1954 }
1955 continue;
1956 }
1957#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001958
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001959 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001960
Yanray Wang78ee0c92023-05-15 11:23:50 +08001961#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001962 if (mode == MBEDTLS_AES_DECRYPT) {
1963 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1964 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001965 } else
1966#endif
1967 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001968 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1969 aes_tests = aes_test_ecb_enc[u];
1970 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001971
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001972 /*
1973 * AES-192 is an optional feature that may be unavailable when
1974 * there is an alternative underlying implementation i.e. when
1975 * MBEDTLS_AES_ALT is defined.
1976 */
1977 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1978 mbedtls_printf("skipped\n");
1979 continue;
1980 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001981 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001982 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001983
1984 for (j = 0; j < 10000; j++) {
1985 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1986 if (ret != 0) {
1987 goto exit;
1988 }
1989 }
1990
1991 if (memcmp(buf, aes_tests, 16) != 0) {
1992 ret = 1;
1993 goto exit;
1994 }
1995
1996 if (verbose != 0) {
1997 mbedtls_printf("passed\n");
1998 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001999 }
2000
Gilles Peskine449bd832023-01-11 14:50:10 +01002001 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002002 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002003 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002004 }
2005
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002006#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002007 /*
2008 * CBC mode
2009 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002010 {
2011 static const int num_tests =
2012 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00002013
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002014 for (i = 0; i < num_tests << 1; i++) {
2015 u = i >> 1;
2016 keybits = 128 + u * 64;
2017 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01002018
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002019 if (verbose != 0) {
2020 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2021 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002022 }
2023
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002024 memset(iv, 0, 16);
2025 memset(prv, 0, 16);
2026 memset(buf, 0, 16);
2027
2028 if (mode == MBEDTLS_AES_DECRYPT) {
2029 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2030 aes_tests = aes_test_cbc_dec[u];
2031 } else {
2032 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2033 aes_tests = aes_test_cbc_enc[u];
2034 }
2035
2036 /*
2037 * AES-192 is an optional feature that may be unavailable when
2038 * there is an alternative underlying implementation i.e. when
2039 * MBEDTLS_AES_ALT is defined.
2040 */
2041 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2042 mbedtls_printf("skipped\n");
2043 continue;
2044 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002045 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002046 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002047
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002048 for (j = 0; j < 10000; j++) {
2049 if (mode == MBEDTLS_AES_ENCRYPT) {
2050 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002051
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002052 memcpy(tmp, prv, 16);
2053 memcpy(prv, buf, 16);
2054 memcpy(buf, tmp, 16);
2055 }
2056
2057 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2058 if (ret != 0) {
2059 goto exit;
2060 }
2061
2062 }
2063
2064 if (memcmp(buf, aes_tests, 16) != 0) {
2065 ret = 1;
2066 goto exit;
2067 }
2068
2069 if (verbose != 0) {
2070 mbedtls_printf("passed\n");
2071 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002072 }
2073
Gilles Peskine449bd832023-01-11 14:50:10 +01002074 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002075 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002076 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002077 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002078#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002079
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002080#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002081 /*
2082 * CFB128 mode
2083 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002084 {
2085 static const int num_tests =
2086 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002087
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002088 for (i = 0; i < num_tests << 1; i++) {
2089 u = i >> 1;
2090 keybits = 128 + u * 64;
2091 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002092
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002093 if (verbose != 0) {
2094 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2095 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2096 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002097
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002098 memcpy(iv, aes_test_cfb128_iv, 16);
2099 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002100
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002101 offset = 0;
2102 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2103 /*
2104 * AES-192 is an optional feature that may be unavailable when
2105 * there is an alternative underlying implementation i.e. when
2106 * MBEDTLS_AES_ALT is defined.
2107 */
2108 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2109 mbedtls_printf("skipped\n");
2110 continue;
2111 } else if (ret != 0) {
2112 goto exit;
2113 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002114
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002115 if (mode == MBEDTLS_AES_DECRYPT) {
2116 memcpy(buf, aes_test_cfb128_ct[u], 64);
2117 aes_tests = aes_test_cfb128_pt;
2118 } else {
2119 memcpy(buf, aes_test_cfb128_pt, 64);
2120 aes_tests = aes_test_cfb128_ct[u];
2121 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002122
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002123 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2124 if (ret != 0) {
2125 goto exit;
2126 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002127
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002128 if (memcmp(buf, aes_tests, 64) != 0) {
2129 ret = 1;
2130 goto exit;
2131 }
2132
2133 if (verbose != 0) {
2134 mbedtls_printf("passed\n");
2135 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002136 }
2137
Gilles Peskine449bd832023-01-11 14:50:10 +01002138 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002139 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002140 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002141 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002142#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002143
Simon Butcherad4e4932018-04-29 00:43:47 +01002144#if defined(MBEDTLS_CIPHER_MODE_OFB)
2145 /*
2146 * OFB mode
2147 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002148 {
2149 static const int num_tests =
2150 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002151
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002152 for (i = 0; i < num_tests << 1; i++) {
2153 u = i >> 1;
2154 keybits = 128 + u * 64;
2155 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002156
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002157 if (verbose != 0) {
2158 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2159 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2160 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002161
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002162 memcpy(iv, aes_test_ofb_iv, 16);
2163 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002164
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002165 offset = 0;
2166 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2167 /*
2168 * AES-192 is an optional feature that may be unavailable when
2169 * there is an alternative underlying implementation i.e. when
2170 * MBEDTLS_AES_ALT is defined.
2171 */
2172 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2173 mbedtls_printf("skipped\n");
2174 continue;
2175 } else if (ret != 0) {
2176 goto exit;
2177 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002178
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002179 if (mode == MBEDTLS_AES_DECRYPT) {
2180 memcpy(buf, aes_test_ofb_ct[u], 64);
2181 aes_tests = aes_test_ofb_pt;
2182 } else {
2183 memcpy(buf, aes_test_ofb_pt, 64);
2184 aes_tests = aes_test_ofb_ct[u];
2185 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002186
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002187 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2188 if (ret != 0) {
2189 goto exit;
2190 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002191
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002192 if (memcmp(buf, aes_tests, 64) != 0) {
2193 ret = 1;
2194 goto exit;
2195 }
2196
2197 if (verbose != 0) {
2198 mbedtls_printf("passed\n");
2199 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002200 }
2201
Gilles Peskine449bd832023-01-11 14:50:10 +01002202 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002203 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002204 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002205 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002206#endif /* MBEDTLS_CIPHER_MODE_OFB */
2207
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002208#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002209 /*
2210 * CTR mode
2211 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002212 {
2213 static const int num_tests =
2214 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002215
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002216 for (i = 0; i < num_tests << 1; i++) {
2217 u = i >> 1;
2218 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002219
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002220 if (verbose != 0) {
2221 mbedtls_printf(" AES-CTR-128 (%s): ",
2222 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2223 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002224
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002225 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2226 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002227
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002228 offset = 0;
2229 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2230 goto exit;
2231 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002232
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002233 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002234
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002235 if (mode == MBEDTLS_AES_DECRYPT) {
2236 memcpy(buf, aes_test_ctr_ct[u], len);
2237 aes_tests = aes_test_ctr_pt[u];
2238 } else {
2239 memcpy(buf, aes_test_ctr_pt[u], len);
2240 aes_tests = aes_test_ctr_ct[u];
2241 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002242
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002243 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2244 stream_block, buf, buf);
2245 if (ret != 0) {
2246 goto exit;
2247 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002248
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002249 if (memcmp(buf, aes_tests, len) != 0) {
2250 ret = 1;
2251 goto exit;
2252 }
2253
2254 if (verbose != 0) {
2255 mbedtls_printf("passed\n");
2256 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002257 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002258 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002259
Gilles Peskine449bd832023-01-11 14:50:10 +01002260 if (verbose != 0) {
2261 mbedtls_printf("\n");
2262 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002263#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002264
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002265#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002266 /*
2267 * XTS mode
2268 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002269 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002270 static const int num_tests =
2271 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2272 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002273
Gilles Peskine449bd832023-01-11 14:50:10 +01002274 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002275
Gilles Peskine449bd832023-01-11 14:50:10 +01002276 for (i = 0; i < num_tests << 1; i++) {
2277 const unsigned char *data_unit;
2278 u = i >> 1;
2279 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002280
Gilles Peskine449bd832023-01-11 14:50:10 +01002281 if (verbose != 0) {
2282 mbedtls_printf(" AES-XTS-128 (%s): ",
2283 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2284 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002285
Gilles Peskine449bd832023-01-11 14:50:10 +01002286 memset(key, 0, sizeof(key));
2287 memcpy(key, aes_test_xts_key[u], 32);
2288 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002289
Gilles Peskine449bd832023-01-11 14:50:10 +01002290 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002291
Gilles Peskine449bd832023-01-11 14:50:10 +01002292 if (mode == MBEDTLS_AES_DECRYPT) {
2293 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2294 if (ret != 0) {
2295 goto exit;
2296 }
2297 memcpy(buf, aes_test_xts_ct32[u], len);
2298 aes_tests = aes_test_xts_pt32[u];
2299 } else {
2300 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2301 if (ret != 0) {
2302 goto exit;
2303 }
2304 memcpy(buf, aes_test_xts_pt32[u], len);
2305 aes_tests = aes_test_xts_ct32[u];
2306 }
2307
2308
2309 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2310 buf, buf);
2311 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002312 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002313 }
2314
2315 if (memcmp(buf, aes_tests, len) != 0) {
2316 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002317 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002318 }
2319
2320 if (verbose != 0) {
2321 mbedtls_printf("passed\n");
2322 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002323 }
2324
Gilles Peskine449bd832023-01-11 14:50:10 +01002325 if (verbose != 0) {
2326 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002327 }
2328
Gilles Peskine449bd832023-01-11 14:50:10 +01002329 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002330 }
2331#endif /* MBEDTLS_CIPHER_MODE_XTS */
2332
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002333 ret = 0;
2334
2335exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002336 if (ret != 0 && verbose != 0) {
2337 mbedtls_printf("failed\n");
2338 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002339
Gilles Peskine449bd832023-01-11 14:50:10 +01002340 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002341
Gilles Peskine449bd832023-01-11 14:50:10 +01002342 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002343}
2344
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002345#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002347#endif /* MBEDTLS_AES_C */