blob: 95ab3921cc7905a62426e8490bba1f5a0a6c2e12 [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
Jerry Yuba42b072023-08-10 12:53:26 +080037#if defined(__aarch64__)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yue62ff092023-08-16 14:15:00 +080043#if defined(__amd64__) || defined(__x86_64__) || \
Jerry Yu372f7a02023-08-18 17:26:25 +080044 ((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))
Jerry Yu02b15192023-04-23 14:43:19 +080045#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080046#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080047#endif
48#endif
49
Jerry Yue62ff092023-08-16 14:15:00 +080050#if defined(__i386__) || defined(_M_IX86)
51#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
52#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080053#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080054
Jerry Yu61fc5ed2023-08-18 17:28:48 +080055#if defined(MBEDTLS_PADLOCK_C)
56#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080057#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
58#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080059#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
60#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
61 "MBEDTLS_PADLOCK_C is set"
62#endif
63#endif
Jerry Yu02b15192023-04-23 14:43:19 +080064#endif
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000067#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000068#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000070#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010071#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080072#if defined(MBEDTLS_AESCE_C)
73#include "aesce.h"
74#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000075
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000076#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020079
Jerry Yu9e628622023-08-17 11:20:09 +080080#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000081static int aes_padlock_ace = -1;
82#endif
83
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000085/*
86 * Forward S-box
87 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010088#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
89 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
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 Wang422a77f2023-07-07 10:12:05 +0800125#endif /* !MBEDTLS_AES_ENCRYPT_ALT || !MBEDTLS_AES_SETKEY_ENC_ALT ||
126 !MBEDTLS_AES_SETKEY_DEC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000127
128/*
129 * Forward tables
130 */
131#define FT \
132\
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
134 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
135 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
136 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
137 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
138 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
139 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
140 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
141 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
142 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
143 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
144 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
145 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
146 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
147 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
148 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
149 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
150 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
151 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
152 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
153 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
154 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
155 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
156 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
157 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
158 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
159 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
160 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
161 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
162 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
163 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
164 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
165 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
166 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
167 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
168 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
169 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
170 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
171 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
172 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
173 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
174 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
175 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
176 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
177 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
178 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
179 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
180 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
181 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
182 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
183 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
184 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
185 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
186 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
187 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
188 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
189 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
190 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
191 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
192 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
193 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
194 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
195 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
196 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 +0000197
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100198#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100199#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000201#undef V
202
Hanno Beckerad049a92017-06-19 16:31:54 +0100203#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000206static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000207#undef V
208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000210static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000211#undef V
212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000215#undef V
216
Hanno Becker177d3cf2017-06-07 15:52:48 +0100217#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200218
Yanray Wang422a77f2023-07-07 10:12:05 +0800219#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
Dave Rodgman1be24632023-06-29 12:01:24 +0100220
Paul Bakker5121ce52009-01-03 21:22:43 +0000221#undef FT
222
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100223#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000224/*
225 * Reverse S-box
226 */
227static const unsigned char RSb[256] =
228{
229 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
230 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
231 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
232 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
233 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
234 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
235 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
236 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
237 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
238 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
239 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
240 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
241 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
242 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
243 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
244 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
245 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
246 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
247 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
248 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
249 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
250 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
251 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
252 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
253 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
254 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
255 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
256 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
257 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
258 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
259 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
260 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
261};
Yanray Wang422a77f2023-07-07 10:12:05 +0800262#endif /* !MBEDTLS_AES_DECRYPT_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264/*
265 * Reverse tables
266 */
267#define RT \
268\
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
270 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
271 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
272 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
273 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
274 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
275 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
276 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
277 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
278 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
279 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
280 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
281 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
282 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
283 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
284 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
285 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
286 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
287 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
288 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
289 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
290 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
291 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
292 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
293 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
294 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
295 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
296 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
297 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
298 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
299 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
300 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
301 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
302 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
303 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
304 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
305 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
306 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
307 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
308 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
309 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
310 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
311 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
312 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
313 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
314 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
315 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
316 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
317 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
318 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
319 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
320 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
321 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
322 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
323 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
324 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
325 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
326 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
327 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
328 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
329 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
330 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
331 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
332 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 +0000333
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100334#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000338#undef V
339
Hanno Beckerad049a92017-06-19 16:31:54 +0100340#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000343static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000344#undef V
345
Gilles Peskine449bd832023-01-11 14:50:10 +0100346#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000348#undef V
349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000352#undef V
353
Hanno Becker177d3cf2017-06-07 15:52:48 +0100354#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200355
Yanray Wang422a77f2023-07-07 10:12:05 +0800356#endif /* !MBEDTLS_AES_DECRYPT_ALT || !MBEDTLS_AES_SETKEY_DEC_ALT */
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800357
Paul Bakker5121ce52009-01-03 21:22:43 +0000358#undef RT
359
Dave Rodgman34152a42023-06-27 18:31:24 +0100360#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000361/*
362 * Round constants
363 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000364static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000365{
366 0x00000001, 0x00000002, 0x00000004, 0x00000008,
367 0x00000010, 0x00000020, 0x00000040, 0x00000080,
368 0x0000001B, 0x00000036
369};
Yanray Wang422a77f2023-07-07 10:12:05 +0800370#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
374/*
375 * Forward S-box & tables
376 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100377#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
378 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000379static unsigned char FSb[256];
Yanray Wang422a77f2023-07-07 10:12:05 +0800380#endif /* !MBEDTLS_AES_ENCRYPT_ALT || !MBEDTLS_AES_SETKEY_ENC_ALT ||
381 !MBEDTLS_AES_SETKEY_DEC_ALT */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100382#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200383static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100384#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200385static uint32_t FT1[256];
386static uint32_t FT2[256];
387static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100388#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang422a77f2023-07-07 10:12:05 +0800389#endif /* !MBEDTLS_AES_ENCRYPT_ALT || !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
391/*
392 * Reverse S-box & tables
393 */
Yanray Wang42742472023-07-07 17:28:24 +0800394
395#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) && !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000396static unsigned char RSb[256];
Yanray Wang42742472023-07-07 17:28:24 +0800397#else /* !MBEDTLS_AES_SETKEY_ENC_ALT && !MBEDTLS_AES_SETKEY_DEC_ALT */
398#if !defined(MBEDTLS_AES_DECRYPT_ALT)
399static unsigned char RSb[256];
400#endif /* !MBEDTLS_AES_DECRYPT_ALT */
401#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT && !MBEDTLS_AES_SETKEY_DEC_ALT */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100402
403#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000404static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100405#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000406static uint32_t RT1[256];
407static uint32_t RT2[256];
408static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100409#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang422a77f2023-07-07 10:12:05 +0800410#endif /* !MBEDTLS_AES_DECRYPT_ALT || !MBEDTLS_AES_SETKEY_DEC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Dave Rodgman8c753f92023-06-27 18:16:13 +0100412#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000413/*
414 * Round constants
415 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000416static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
418/*
419 * Tables generation code
420 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
422#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
423#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
425static int aes_init_done = 0;
426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000428{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800429 int i;
430 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800431 uint8_t pow[256];
432 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 /*
435 * compute pow and log tables over GF(2^8)
436 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800439 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800440 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 }
442
443 /*
444 * calculate the round constants
445 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800447 RCON[i] = x;
448 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 }
450
451 /*
452 * generate the forward and reverse S-boxes
453 */
454 FSb[0x00] = 0x63;
Yanray Wang42742472023-07-07 17:28:24 +0800455#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 RSb[0x63] = 0x00;
Yanray Wang42742472023-07-07 17:28:24 +0800457#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000460 x = pow[255 - log[i]];
461
Yanray Wangfe944ce2023-06-26 18:16:01 +0800462 y = x; y = (y << 1) | (y >> 7);
463 x ^= y; y = (y << 1) | (y >> 7);
464 x ^= y; y = (y << 1) | (y >> 7);
465 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 x ^= y ^ 0x63;
467
Yanray Wangfe944ce2023-06-26 18:16:01 +0800468 FSb[i] = x;
Yanray Wang42742472023-07-07 17:28:24 +0800469#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000470 RSb[x] = (unsigned char) i;
Yanray Wang42742472023-07-07 17:28:24 +0800471#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000472 }
473
474 /*
475 * generate the forward and reverse tables
476 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000478 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800479 y = XTIME(x);
480 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000481
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 FT0[i] = ((uint32_t) y) ^
483 ((uint32_t) x << 8) ^
484 ((uint32_t) x << 16) ^
485 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
Hanno Beckerad049a92017-06-19 16:31:54 +0100487#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 FT1[i] = ROTL8(FT0[i]);
489 FT2[i] = ROTL8(FT1[i]);
490 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100491#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
Yanray Wang42742472023-07-07 17:28:24 +0800493#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000494 x = RSb[i];
495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
497 ((uint32_t) MUL(0x09, x) << 8) ^
498 ((uint32_t) MUL(0x0D, x) << 16) ^
499 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
Hanno Beckerad049a92017-06-19 16:31:54 +0100501#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 RT1[i] = ROTL8(RT0[i]);
503 RT2[i] = ROTL8(RT1[i]);
504 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100505#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang422a77f2023-07-07 10:12:05 +0800506#endif /* !MBEDTLS_AES_DECRYPT_ALT || !MBEDTLS_AES_SETKEY_DEC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000507 }
508}
509
Yanray Wang422a77f2023-07-07 10:12:05 +0800510#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Dave Rodgman8c753f92023-06-27 18:16:13 +0100511
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200512#undef ROTL8
513
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200514#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000515
Hanno Beckerad049a92017-06-19 16:31:54 +0100516#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
519#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
520#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200521
522#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100523#define AES_RT1(idx) ROTL8(RT0[idx])
524#define AES_RT2(idx) ROTL16(RT0[idx])
525#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200526
527#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100528#define AES_FT1(idx) ROTL8(FT0[idx])
529#define AES_FT2(idx) ROTL16(FT0[idx])
530#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200531
Hanno Becker177d3cf2017-06-07 15:52:48 +0100532#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200533
534#define AES_RT0(idx) RT0[idx]
535#define AES_RT1(idx) RT1[idx]
536#define AES_RT2(idx) RT2[idx]
537#define AES_RT3(idx) RT3[idx]
538
539#define AES_FT0(idx) FT0[idx]
540#define AES_FT1(idx) FT1[idx]
541#define AES_FT2(idx) FT2[idx]
542#define AES_FT3(idx) FT3[idx]
543
Hanno Becker177d3cf2017-06-07 15:52:48 +0100544#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200545
Gilles Peskine449bd832023-01-11 14:50:10 +0100546void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200547{
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200549}
550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200552{
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200554 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200558}
559
Jaeden Amero9366feb2018-05-29 18:55:17 +0100560#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100561void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100562{
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 mbedtls_aes_init(&ctx->crypt);
564 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100565}
566
Gilles Peskine449bd832023-01-11 14:50:10 +0100567void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100568{
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100570 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 }
Simon Butcher5201e412018-12-06 17:40:14 +0000572
Gilles Peskine449bd832023-01-11 14:50:10 +0100573 mbedtls_aes_free(&ctx->crypt);
574 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100575}
576#endif /* MBEDTLS_CIPHER_MODE_XTS */
577
Gilles Peskine0de8f852023-03-16 17:14:59 +0100578/* Some implementations need the round keys to be aligned.
579 * Return an offset to be added to buf, such that (buf + offset) is
580 * correctly aligned.
581 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
582 * i.e. an offset of 1 means 4 bytes and so on.
583 */
Jerry Yu96084472023-08-17 18:10:45 +0800584#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100585 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100586#define MAY_NEED_TO_ALIGN
587#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100588
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100589#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
590 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100591static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
592{
593#if defined(MAY_NEED_TO_ALIGN)
594 int align_16_bytes = 0;
595
Jerry Yu9e628622023-08-17 11:20:09 +0800596#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100597 if (aes_padlock_ace == -1) {
598 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
599 }
600 if (aes_padlock_ace) {
601 align_16_bytes = 1;
602 }
603#endif
604
Gilles Peskine9c682e72023-03-16 17:21:33 +0100605#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100606 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
607 align_16_bytes = 1;
608 }
609#endif
610
611 if (align_16_bytes) {
612 /* These implementations needs 16-byte alignment
613 * for the round key array. */
614 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
615 if (delta == 0) {
616 return 0;
617 } else {
618 return 4 - delta; // 16 bytes = 4 uint32_t
619 }
620 }
621#else /* MAY_NEED_TO_ALIGN */
622 (void) buf;
623#endif /* MAY_NEED_TO_ALIGN */
624
625 return 0;
626}
Yanray Wang422a77f2023-07-07 10:12:05 +0800627#endif /* MAY_NEED_TO_ALIGN || !MBEDTLS_AES_SETKEY_DEC_ALT ||
628 !MBEDTLS_AES_SETKEY_ENC_ALT */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100629
Paul Bakker5121ce52009-01-03 21:22:43 +0000630/*
631 * AES key schedule (encryption)
632 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200633#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100634int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
635 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000636{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000637 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800641#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000642 case 192: ctx->nr = 12; break;
643 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800644#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 }
647
Simon Butcher5201e412018-12-06 17:40:14 +0000648#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000650 aes_gen_tables();
651 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000652 }
653#endif
654
Gilles Peskine0de8f852023-03-16 17:14:59 +0100655 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100656 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000657
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100658#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
660 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
661 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100662#endif
663
Jerry Yu3f2fb712023-01-10 17:05:42 +0800664#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100665 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800666 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
667 }
668#endif
669
Jerry Yu29c91ba2023-08-04 11:02:04 +0800670#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800671 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 }
674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000676 case 10:
677
Jerry Yu3a0f0442023-08-17 17:06:21 +0800678 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000679 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
681 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
682 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
683 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
685 RK[5] = RK[1] ^ RK[4];
686 RK[6] = RK[2] ^ RK[5];
687 RK[7] = RK[3] ^ RK[6];
688 }
689 break;
690
Arto Kinnunen732ca322023-04-14 14:26:10 +0800691#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000692 case 12:
693
Jerry Yu3a0f0442023-08-17 17:06:21 +0800694 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
697 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
698 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
699 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701 RK[7] = RK[1] ^ RK[6];
702 RK[8] = RK[2] ^ RK[7];
703 RK[9] = RK[3] ^ RK[8];
704 RK[10] = RK[4] ^ RK[9];
705 RK[11] = RK[5] ^ RK[10];
706 }
707 break;
708
709 case 14:
710
Jerry Yu3a0f0442023-08-17 17:06:21 +0800711 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000712 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
714 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
715 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
716 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
718 RK[9] = RK[1] ^ RK[8];
719 RK[10] = RK[2] ^ RK[9];
720 RK[11] = RK[3] ^ RK[10];
721
722 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
724 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
725 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
726 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
728 RK[13] = RK[5] ^ RK[12];
729 RK[14] = RK[6] ^ RK[13];
730 RK[15] = RK[7] ^ RK[14];
731 }
732 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800733#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000734 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000735
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800737#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000738}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200739#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000740
741/*
742 * AES key schedule (decryption)
743 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200744#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100745int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
746 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000747{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800748#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800749 uint32_t *SK;
750#endif
751 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200752 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000753 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800754
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200755
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000757
Gilles Peskine0de8f852023-03-16 17:14:59 +0100758 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100759 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000760
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200761 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200763 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000765
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200766 ctx->nr = cty.nr;
767
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100768#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
770 mbedtls_aesni_inverse_key((unsigned char *) RK,
771 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200772 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100773 }
774#endif
775
Jerry Yue096da12023-01-10 17:07:01 +0800776#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100777 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800778 mbedtls_aesce_inverse_key(
779 (unsigned char *) RK,
780 (const unsigned char *) (cty.buf + cty.rk_offset),
781 ctx->nr);
782 goto exit;
783 }
784#endif
785
Jerry Yu29c91ba2023-08-04 11:02:04 +0800786#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100787 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000788
789 *RK++ = *SK++;
790 *RK++ = *SK++;
791 *RK++ = *SK++;
792 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800793 SK -= 8;
794 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
795 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
797 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
798 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
799 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000800 }
801 }
802
803 *RK++ = *SK++;
804 *RK++ = *SK++;
805 *RK++ = *SK++;
806 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800807#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200808exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000810
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000812}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100813#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100814
815#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100816static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
817 unsigned int keybits,
818 const unsigned char **key1,
819 unsigned int *key1bits,
820 const unsigned char **key2,
821 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100822{
823 const unsigned int half_keybits = keybits / 2;
824 const unsigned int half_keybytes = half_keybits / 8;
825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100827 case 256: break;
828 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100830 }
831
832 *key1bits = half_keybits;
833 *key2bits = half_keybits;
834 *key1 = &key[0];
835 *key2 = &key[half_keybytes];
836
837 return 0;
838}
839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
841 const unsigned char *key,
842 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100843{
Janos Follath24eed8d2019-11-22 13:21:35 +0000844 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100845 const unsigned char *key1, *key2;
846 unsigned int key1bits, key2bits;
847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
849 &key2, &key2bits);
850 if (ret != 0) {
851 return ret;
852 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100853
854 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
856 if (ret != 0) {
857 return ret;
858 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100859
860 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100862}
863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
865 const unsigned char *key,
866 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100867{
Janos Follath24eed8d2019-11-22 13:21:35 +0000868 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100869 const unsigned char *key1, *key2;
870 unsigned int key1bits, key2bits;
871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
873 &key2, &key2bits);
874 if (ret != 0) {
875 return ret;
876 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100877
878 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
880 if (ret != 0) {
881 return ret;
882 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100883
884 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100886}
887#endif /* MBEDTLS_CIPHER_MODE_XTS */
888
Gilles Peskine449bd832023-01-11 14:50:10 +0100889#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100890 do \
891 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
893 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
894 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
895 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100896 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
898 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
899 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
900 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100901 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
903 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
904 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
905 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100906 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
908 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
909 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
910 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
911 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100914 do \
915 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
917 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
918 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
919 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100920 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
922 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
923 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
924 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100925 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
927 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
928 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
929 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100930 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
932 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
933 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
934 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
935 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000936
937/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200938 * AES-ECB block encryption
939 */
940#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100941int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
942 const unsigned char input[16],
943 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200944{
945 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100946 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200948 uint32_t X[4];
949 uint32_t Y[4];
950 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200951
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
953 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
954 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
955 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200956
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
958 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]);
959 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 +0200960 }
961
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 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 +0200963
Gilles Peskine5197c662020-08-26 17:03:24 +0200964 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
966 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
967 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200969
Gilles Peskine5197c662020-08-26 17:03:24 +0200970 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
972 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
973 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
974 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200975
Gilles Peskine5197c662020-08-26 17:03:24 +0200976 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
978 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
979 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
980 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200981
Gilles Peskine5197c662020-08-26 17:03:24 +0200982 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
984 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
985 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
986 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200987
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
989 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
990 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
991 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996}
997#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
998
999/*
1000 * AES-ECB block decryption
1001 */
1002#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +01001003int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
1004 const unsigned char input[16],
1005 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001006{
1007 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +01001008 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001010 uint32_t X[4];
1011 uint32_t Y[4];
1012 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1015 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1016 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1017 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001018
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1020 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]);
1021 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 +02001022 }
1023
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 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 +02001025
Gilles Peskine5197c662020-08-26 17:03:24 +02001026 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1028 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1029 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001031
Gilles Peskine5197c662020-08-26 17:03:24 +02001032 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1034 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1035 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1036 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001037
Gilles Peskine5197c662020-08-26 17:03:24 +02001038 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1040 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1041 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1042 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001043
Gilles Peskine5197c662020-08-26 17:03:24 +02001044 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1046 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1047 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1048 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001049
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1051 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1052 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1053 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001056
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001058}
1059#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1060
Gilles Peskine0de8f852023-03-16 17:14:59 +01001061#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001062/* VIA Padlock and our intrinsics-based implementation of AESNI require
1063 * the round keys to be aligned on a 16-byte boundary. We take care of this
1064 * before creating them, but the AES context may have moved (this can happen
1065 * if the library is called from a language with managed memory), and in later
1066 * calls it might have a different alignment with respect to 16-byte memory.
1067 * So we may need to realign.
1068 */
1069static void aes_maybe_realign(mbedtls_aes_context *ctx)
1070{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001071 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1072 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001073 memmove(ctx->buf + new_offset, // new address
1074 ctx->buf + ctx->rk_offset, // current address
1075 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1076 ctx->rk_offset = new_offset;
1077 }
1078}
1079#endif
1080
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001081/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001082 * AES-ECB block encryption/decryption
1083 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001084int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1085 int mode,
1086 const unsigned char input[16],
1087 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001088{
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001090 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001092
Gilles Peskine0de8f852023-03-16 17:14:59 +01001093#if defined(MAY_NEED_TO_ALIGN)
1094 aes_maybe_realign(ctx);
1095#endif
1096
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001097#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1099 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1100 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001101#endif
1102
Jerry Yu2bb3d812023-01-10 17:38:26 +08001103#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001104 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001105 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1106 }
1107#endif
1108
Jerry Yu9e628622023-08-17 11:20:09 +08001109#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001111 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001112 }
1113#endif
1114
Jerry Yu29c91ba2023-08-04 11:02:04 +08001115#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 if (mode == MBEDTLS_AES_ENCRYPT) {
1117 return mbedtls_internal_aes_encrypt(ctx, input, output);
1118 } else {
1119 return mbedtls_internal_aes_decrypt(ctx, input, output);
1120 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001121#endif
1122
Paul Bakker5121ce52009-01-03 21:22:43 +00001123}
1124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001125#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001126
Paul Bakker5121ce52009-01-03 21:22:43 +00001127/*
1128 * AES-CBC buffer encryption/decryption
1129 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001130int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1131 int mode,
1132 size_t length,
1133 unsigned char iv[16],
1134 const unsigned char *input,
1135 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001136{
Gilles Peskine7820a572021-07-07 21:08:28 +02001137 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001138 unsigned char temp[16];
1139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001141 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001143
Paul Elliott2ad93672023-08-11 11:07:06 +01001144 /* Nothing to do if length is zero. */
1145 if (length == 0) {
1146 return 0;
1147 }
1148
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 if (length % 16) {
1150 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1151 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001152
Jerry Yu9e628622023-08-17 11:20:09 +08001153#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 if (aes_padlock_ace > 0) {
1155 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1156 return 0;
1157 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001158
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001159 // If padlock data misaligned, we just fall back to
1160 // unaccelerated mode
1161 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001162 }
1163#endif
1164
Dave Rodgman906c63c2023-06-14 17:53:51 +01001165 const unsigned char *ivp = iv;
1166
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 if (mode == MBEDTLS_AES_DECRYPT) {
1168 while (length > 0) {
1169 memcpy(temp, input, 16);
1170 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1171 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001172 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001174 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001175 * the result for the next block in CBC, and the cost of transferring that data from
1176 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001177 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001178
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001180
1181 input += 16;
1182 output += 16;
1183 length -= 16;
1184 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 } else {
1186 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001187 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001188
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1190 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001191 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001193 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001194
1195 input += 16;
1196 output += 16;
1197 length -= 16;
1198 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001199 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001200 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001201 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001202
Gilles Peskine7820a572021-07-07 21:08:28 +02001203exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001204 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001205}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001206#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001207
Aorimn5f778012016-06-09 23:22:58 +02001208#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001209
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001210typedef unsigned char mbedtls_be128[16];
1211
1212/*
1213 * GF(2^128) multiplication function
1214 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001215 * This function multiplies a field element by x in the polynomial field
1216 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001217 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001218 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001219 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001220#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001221MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001222#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001223static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001224 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001225{
1226 uint64_t a, b, ra, rb;
1227
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 a = MBEDTLS_GET_UINT64_LE(x, 0);
1229 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001230
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1232 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001233
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1235 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001236}
1237
Aorimn5f778012016-06-09 23:22:58 +02001238/*
1239 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001240 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001241 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001242 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001243 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001244#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001245MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001246#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001247int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1248 int mode,
1249 size_t length,
1250 const unsigned char data_unit[16],
1251 const unsigned char *input,
1252 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001253{
Janos Follath24eed8d2019-11-22 13:21:35 +00001254 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001255 size_t blocks = length / 16;
1256 size_t leftover = length % 16;
1257 unsigned char tweak[16];
1258 unsigned char prev_tweak[16];
1259 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001260
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001262 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001264
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001265 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001266 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001267 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 }
Aorimn5f778012016-06-09 23:22:58 +02001269
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001270 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001272 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 }
Aorimn5f778012016-06-09 23:22:58 +02001274
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001276 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1277 data_unit, tweak);
1278 if (ret != 0) {
1279 return ret;
1280 }
Aorimn5f778012016-06-09 23:22:58 +02001281
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001283 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001284 /* We are on the last block in a decrypt operation that has
1285 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001286 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001287 * the leftovers and then update the current tweak for use on this,
1288 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 memcpy(prev_tweak, tweak, sizeof(tweak));
1290 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001291 }
1292
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1296 if (ret != 0) {
1297 return ret;
1298 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001299
Gilles Peskine449bd832023-01-11 14:50:10 +01001300 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001301
1302 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001303 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001304
1305 output += 16;
1306 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001307 }
1308
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001310 /* If we are on the leftover bytes in a decrypt operation, we need to
1311 * use the previous tweak for these bytes (as saved in prev_tweak). */
1312 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001313
Jaeden Amerod82cd862018-04-28 15:02:45 +01001314 /* We are now on the final part of the data unit, which doesn't divide
1315 * evenly by 16. It's time for ciphertext stealing. */
1316 size_t i;
1317 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001318
Jaeden Amerod82cd862018-04-28 15:02:45 +01001319 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001320 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001321 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001322 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001323 }
Aorimn5f778012016-06-09 23:22:58 +02001324
Dave Rodgman069e7f42022-11-24 19:37:26 +00001325 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001327
Jaeden Amerod82cd862018-04-28 15:02:45 +01001328 /* Copy ciphertext bytes from the previous block for input in this
1329 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001331
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1333 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001334 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 }
Aorimn5f778012016-06-09 23:22:58 +02001336
Jaeden Amerod82cd862018-04-28 15:02:45 +01001337 /* Write the result back to the previous block, overriding the previous
1338 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001340 }
1341
Gilles Peskine449bd832023-01-11 14:50:10 +01001342 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001343}
1344#endif /* MBEDTLS_CIPHER_MODE_XTS */
1345
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001346#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001347/*
1348 * AES-CFB128 buffer encryption/decryption
1349 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001350int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1351 int mode,
1352 size_t length,
1353 size_t *iv_off,
1354 unsigned char iv[16],
1355 const unsigned char *input,
1356 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001357{
Paul Bakker27fdf462011-06-09 13:55:13 +00001358 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001359 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001360 size_t n;
1361
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001363 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001365
1366 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001367
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 if (n > 15) {
1369 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1370 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001371
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 if (mode == MBEDTLS_AES_DECRYPT) {
1373 while (length--) {
1374 if (n == 0) {
1375 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1376 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001377 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001379 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001380
1381 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001383 iv[n] = (unsigned char) c;
1384
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001386 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 } else {
1388 while (length--) {
1389 if (n == 0) {
1390 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1391 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001392 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001394 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001395
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001397
Gilles Peskine449bd832023-01-11 14:50:10 +01001398 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001399 }
1400 }
1401
1402 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001403 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001404
Gilles Peskine7820a572021-07-07 21:08:28 +02001405exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001406 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001407}
Paul Bakker556efba2014-01-24 15:38:12 +01001408
1409/*
1410 * AES-CFB8 buffer encryption/decryption
1411 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001412int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1413 int mode,
1414 size_t length,
1415 unsigned char iv[16],
1416 const unsigned char *input,
1417 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001418{
Gilles Peskine7820a572021-07-07 21:08:28 +02001419 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001420 unsigned char c;
1421 unsigned char ov[17];
1422
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001424 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 }
1426 while (length--) {
1427 memcpy(ov, iv, 16);
1428 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1429 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001430 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001431 }
Paul Bakker556efba2014-01-24 15:38:12 +01001432
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001434 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001435 }
Paul Bakker556efba2014-01-24 15:38:12 +01001436
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001438
Gilles Peskine449bd832023-01-11 14:50:10 +01001439 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001440 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001441 }
Paul Bakker556efba2014-01-24 15:38:12 +01001442
Gilles Peskine449bd832023-01-11 14:50:10 +01001443 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001444 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001445 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001446
Gilles Peskine7820a572021-07-07 21:08:28 +02001447exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001448 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001449}
Simon Butcher76a5b222018-04-22 22:57:27 +01001450#endif /* MBEDTLS_CIPHER_MODE_CFB */
1451
1452#if defined(MBEDTLS_CIPHER_MODE_OFB)
1453/*
1454 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1455 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001456int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1457 size_t length,
1458 size_t *iv_off,
1459 unsigned char iv[16],
1460 const unsigned char *input,
1461 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001462{
Simon Butcherad4e4932018-04-29 00:43:47 +01001463 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001464 size_t n;
1465
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001466 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001467
Gilles Peskine449bd832023-01-11 14:50:10 +01001468 if (n > 15) {
1469 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1470 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001471
Gilles Peskine449bd832023-01-11 14:50:10 +01001472 while (length--) {
1473 if (n == 0) {
1474 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1475 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001476 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001477 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001478 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001479 *output++ = *input++ ^ iv[n];
1480
Gilles Peskine449bd832023-01-11 14:50:10 +01001481 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001482 }
1483
1484 *iv_off = n;
1485
Simon Butcherad4e4932018-04-29 00:43:47 +01001486exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001487 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001488}
1489#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001492/*
1493 * AES-CTR buffer encryption/decryption
1494 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001495int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1496 size_t length,
1497 size_t *nc_off,
1498 unsigned char nonce_counter[16],
1499 unsigned char stream_block[16],
1500 const unsigned char *input,
1501 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001502{
Paul Bakker369e14b2012-04-18 14:16:09 +00001503 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001504 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001505 size_t n;
1506
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001507 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001508
Gilles Peskine449bd832023-01-11 14:50:10 +01001509 if (n > 0x0F) {
1510 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1511 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001512
Gilles Peskine449bd832023-01-11 14:50:10 +01001513 while (length--) {
1514 if (n == 0) {
1515 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1516 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001517 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001518 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001519
Gilles Peskine449bd832023-01-11 14:50:10 +01001520 for (i = 16; i > 0; i--) {
1521 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001522 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001523 }
1524 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001525 }
1526 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001527 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001528
Gilles Peskine449bd832023-01-11 14:50:10 +01001529 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001530 }
1531
1532 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001533 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001534
Gilles Peskine7820a572021-07-07 21:08:28 +02001535exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001536 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001537}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001541
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001543/*
1544 * AES test vectors from:
1545 *
1546 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1547 */
Yanray Wang62c99912023-05-11 11:06:53 +08001548static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001549{
1550 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1551 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001552#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001553 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1554 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1555 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1556 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001557#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001558};
1559
Yanray Wang62c99912023-05-11 11:06:53 +08001560static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001561{
1562 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1563 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001564#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001565 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1566 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1567 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1568 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001569#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001570};
1571
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001572#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001573static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001574{
1575 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1576 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001577#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001578 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1579 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1580 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1581 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001582#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001583};
1584
Yanray Wang62c99912023-05-11 11:06:53 +08001585static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001586{
1587 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1588 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001589#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001590 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1591 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1592 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1593 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001594#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001595};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001596#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001597
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001598#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001599/*
1600 * AES-CFB128 test vectors from:
1601 *
1602 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1603 */
Yanray Wang62c99912023-05-11 11:06:53 +08001604static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001605{
1606 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1607 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001608#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001609 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1610 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1611 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1612 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1613 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1614 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1615 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001616#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001617};
1618
1619static const unsigned char aes_test_cfb128_iv[16] =
1620{
1621 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1622 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1623};
1624
1625static const unsigned char aes_test_cfb128_pt[64] =
1626{
1627 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1628 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1629 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1630 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1631 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1632 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1633 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1634 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1635};
1636
Yanray Wang62c99912023-05-11 11:06:53 +08001637static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001638{
1639 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1640 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1641 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1642 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1643 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1644 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1645 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1646 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001647#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001648 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1649 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1650 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1651 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1652 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1653 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1654 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1655 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1656 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1657 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1658 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1659 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1660 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1661 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1662 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1663 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001664#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001665};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001666#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001667
Simon Butcherad4e4932018-04-29 00:43:47 +01001668#if defined(MBEDTLS_CIPHER_MODE_OFB)
1669/*
1670 * AES-OFB test vectors from:
1671 *
Simon Butcher5db13622018-06-04 22:11:25 +01001672 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001673 */
Yanray Wang62c99912023-05-11 11:06:53 +08001674static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001675{
1676 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1677 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001678#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001679 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1680 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1681 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1682 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1683 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1684 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1685 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001686#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001687};
1688
1689static const unsigned char aes_test_ofb_iv[16] =
1690{
1691 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1692 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1693};
1694
1695static const unsigned char aes_test_ofb_pt[64] =
1696{
1697 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1698 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1699 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1700 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1701 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1702 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1703 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1704 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1705};
1706
Yanray Wang62c99912023-05-11 11:06:53 +08001707static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001708{
1709 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1710 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1711 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1712 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1713 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1714 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1715 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1716 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001717#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001718 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1719 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1720 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1721 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1722 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1723 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1724 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1725 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1726 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1727 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1728 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1729 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1730 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1731 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1732 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1733 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001734#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001735};
1736#endif /* MBEDTLS_CIPHER_MODE_OFB */
1737
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001738#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001739/*
1740 * AES-CTR test vectors from:
1741 *
1742 * http://www.faqs.org/rfcs/rfc3686.html
1743 */
1744
Yanray Wang62c99912023-05-11 11:06:53 +08001745static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001746{
1747 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1748 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1749 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1750 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1751 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1752 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1753};
1754
Yanray Wang62c99912023-05-11 11:06:53 +08001755static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001756{
1757 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1759 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1760 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1761 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1762 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1763};
1764
Yanray Wang62c99912023-05-11 11:06:53 +08001765static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001766{
1767 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1768 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001769 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1770 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1771 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1772 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1773
1774 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1775 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1776 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1777 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1778 0x20, 0x21, 0x22, 0x23 }
1779};
1780
Yanray Wang62c99912023-05-11 11:06:53 +08001781static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001782{
1783 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1784 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1785 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1786 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1787 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1788 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1789 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1790 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1791 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1792 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1793 0x25, 0xB2, 0x07, 0x2F }
1794};
1795
1796static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001797{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001798#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001799
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001800#if defined(MBEDTLS_CIPHER_MODE_XTS)
1801/*
1802 * AES-XTS test vectors from:
1803 *
1804 * IEEE P1619/D16 Annex B
1805 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1806 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1807 */
1808static const unsigned char aes_test_xts_key[][32] =
1809{
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1814 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1815 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1816 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1817 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1818 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1819 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1820 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1821 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1822};
1823
1824static const unsigned char aes_test_xts_pt32[][32] =
1825{
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1838};
1839
1840static const unsigned char aes_test_xts_ct32[][32] =
1841{
1842 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1843 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1844 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1845 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1846 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1847 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1848 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1849 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1850 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1851 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1852 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1853 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1854};
1855
1856static const unsigned char aes_test_xts_data_unit[][16] =
1857{
Gilles Peskine449bd832023-01-11 14:50:10 +01001858 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1860 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1862 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001864};
1865
1866#endif /* MBEDTLS_CIPHER_MODE_XTS */
1867
Paul Bakker5121ce52009-01-03 21:22:43 +00001868/*
1869 * Checkup routine
1870 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001871int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001872{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001873 int ret = 0, i, j, u, mode;
1874 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001875 unsigned char key[32];
1876 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001877 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001878#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1879 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001880 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001881#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001882#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001883 unsigned char prv[16];
1884#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001885#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1886 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001887 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001888#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001889#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001890 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001891#endif
1892#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001893 unsigned char nonce_counter[16];
1894 unsigned char stream_block[16];
1895#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001896 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001897
Gilles Peskine449bd832023-01-11 14:50:10 +01001898 memset(key, 0, 32);
1899 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001900
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001901 if (verbose != 0) {
1902#if defined(MBEDTLS_AES_ALT)
1903 mbedtls_printf(" AES note: alternative implementation.\n");
1904#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001905#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001906#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001907 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001908#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001909 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001910#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001911#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001912#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001913 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1914 mbedtls_printf(" AES note: using AESNI.\n");
1915 } else
1916#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001917#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001918 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1919 mbedtls_printf(" AES note: using VIA Padlock.\n");
1920 } else
1921#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001922#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001923 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001924 mbedtls_printf(" AES note: using AESCE.\n");
1925 } else
1926#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001927 {
1928#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1929 mbedtls_printf(" AES note: built-in implementation.\n");
1930#endif
1931 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001932#endif /* MBEDTLS_AES_ALT */
1933 }
1934
Paul Bakker5121ce52009-01-03 21:22:43 +00001935 /*
1936 * ECB mode
1937 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001938 {
1939 static const int num_tests =
1940 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001941
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001942 for (i = 0; i < num_tests << 1; i++) {
1943 u = i >> 1;
1944 keybits = 128 + u * 64;
1945 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001946
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001947 if (verbose != 0) {
1948 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1949 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1950 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001951
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001952 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001953
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001954 if (mode == MBEDTLS_AES_DECRYPT) {
1955 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1956 aes_tests = aes_test_ecb_dec[u];
1957 } else {
1958 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1959 aes_tests = aes_test_ecb_enc[u];
1960 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001961
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001962 /*
1963 * AES-192 is an optional feature that may be unavailable when
1964 * there is an alternative underlying implementation i.e. when
1965 * MBEDTLS_AES_ALT is defined.
1966 */
1967 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1968 mbedtls_printf("skipped\n");
1969 continue;
1970 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001971 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001972 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001973
1974 for (j = 0; j < 10000; j++) {
1975 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1976 if (ret != 0) {
1977 goto exit;
1978 }
1979 }
1980
1981 if (memcmp(buf, aes_tests, 16) != 0) {
1982 ret = 1;
1983 goto exit;
1984 }
1985
1986 if (verbose != 0) {
1987 mbedtls_printf("passed\n");
1988 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001989 }
1990
Gilles Peskine449bd832023-01-11 14:50:10 +01001991 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001992 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001993 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001994 }
1995
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001996#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001997 /*
1998 * CBC mode
1999 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002000 {
2001 static const int num_tests =
2002 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00002003
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002004 for (i = 0; i < num_tests << 1; i++) {
2005 u = i >> 1;
2006 keybits = 128 + u * 64;
2007 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01002008
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002009 if (verbose != 0) {
2010 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2011 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002012 }
2013
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002014 memset(iv, 0, 16);
2015 memset(prv, 0, 16);
2016 memset(buf, 0, 16);
2017
2018 if (mode == MBEDTLS_AES_DECRYPT) {
2019 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2020 aes_tests = aes_test_cbc_dec[u];
2021 } else {
2022 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2023 aes_tests = aes_test_cbc_enc[u];
2024 }
2025
2026 /*
2027 * AES-192 is an optional feature that may be unavailable when
2028 * there is an alternative underlying implementation i.e. when
2029 * MBEDTLS_AES_ALT is defined.
2030 */
2031 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2032 mbedtls_printf("skipped\n");
2033 continue;
2034 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002035 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002036 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002037
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002038 for (j = 0; j < 10000; j++) {
2039 if (mode == MBEDTLS_AES_ENCRYPT) {
2040 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002041
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002042 memcpy(tmp, prv, 16);
2043 memcpy(prv, buf, 16);
2044 memcpy(buf, tmp, 16);
2045 }
2046
2047 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2048 if (ret != 0) {
2049 goto exit;
2050 }
2051
2052 }
2053
2054 if (memcmp(buf, aes_tests, 16) != 0) {
2055 ret = 1;
2056 goto exit;
2057 }
2058
2059 if (verbose != 0) {
2060 mbedtls_printf("passed\n");
2061 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 }
2063
Gilles Peskine449bd832023-01-11 14:50:10 +01002064 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002065 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002066 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002067 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002068#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002069
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002070#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002071 /*
2072 * CFB128 mode
2073 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002074 {
2075 static const int num_tests =
2076 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002077
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002078 for (i = 0; i < num_tests << 1; i++) {
2079 u = i >> 1;
2080 keybits = 128 + u * 64;
2081 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002082
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002083 if (verbose != 0) {
2084 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2085 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2086 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002087
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002088 memcpy(iv, aes_test_cfb128_iv, 16);
2089 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002091 offset = 0;
2092 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2093 /*
2094 * AES-192 is an optional feature that may be unavailable when
2095 * there is an alternative underlying implementation i.e. when
2096 * MBEDTLS_AES_ALT is defined.
2097 */
2098 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2099 mbedtls_printf("skipped\n");
2100 continue;
2101 } else if (ret != 0) {
2102 goto exit;
2103 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002104
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002105 if (mode == MBEDTLS_AES_DECRYPT) {
2106 memcpy(buf, aes_test_cfb128_ct[u], 64);
2107 aes_tests = aes_test_cfb128_pt;
2108 } else {
2109 memcpy(buf, aes_test_cfb128_pt, 64);
2110 aes_tests = aes_test_cfb128_ct[u];
2111 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002112
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002113 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2114 if (ret != 0) {
2115 goto exit;
2116 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002117
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002118 if (memcmp(buf, aes_tests, 64) != 0) {
2119 ret = 1;
2120 goto exit;
2121 }
2122
2123 if (verbose != 0) {
2124 mbedtls_printf("passed\n");
2125 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002126 }
2127
Gilles Peskine449bd832023-01-11 14:50:10 +01002128 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002129 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002130 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002131 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002132#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002133
Simon Butcherad4e4932018-04-29 00:43:47 +01002134#if defined(MBEDTLS_CIPHER_MODE_OFB)
2135 /*
2136 * OFB mode
2137 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002138 {
2139 static const int num_tests =
2140 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002141
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002142 for (i = 0; i < num_tests << 1; i++) {
2143 u = i >> 1;
2144 keybits = 128 + u * 64;
2145 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002146
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002147 if (verbose != 0) {
2148 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2149 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2150 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002151
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002152 memcpy(iv, aes_test_ofb_iv, 16);
2153 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002154
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002155 offset = 0;
2156 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2157 /*
2158 * AES-192 is an optional feature that may be unavailable when
2159 * there is an alternative underlying implementation i.e. when
2160 * MBEDTLS_AES_ALT is defined.
2161 */
2162 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2163 mbedtls_printf("skipped\n");
2164 continue;
2165 } else if (ret != 0) {
2166 goto exit;
2167 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002168
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002169 if (mode == MBEDTLS_AES_DECRYPT) {
2170 memcpy(buf, aes_test_ofb_ct[u], 64);
2171 aes_tests = aes_test_ofb_pt;
2172 } else {
2173 memcpy(buf, aes_test_ofb_pt, 64);
2174 aes_tests = aes_test_ofb_ct[u];
2175 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002176
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002177 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2178 if (ret != 0) {
2179 goto exit;
2180 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002181
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002182 if (memcmp(buf, aes_tests, 64) != 0) {
2183 ret = 1;
2184 goto exit;
2185 }
2186
2187 if (verbose != 0) {
2188 mbedtls_printf("passed\n");
2189 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002190 }
2191
Gilles Peskine449bd832023-01-11 14:50:10 +01002192 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002193 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002194 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002195 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002196#endif /* MBEDTLS_CIPHER_MODE_OFB */
2197
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002198#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002199 /*
2200 * CTR mode
2201 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002202 {
2203 static const int num_tests =
2204 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002205
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002206 for (i = 0; i < num_tests << 1; i++) {
2207 u = i >> 1;
2208 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002209
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002210 if (verbose != 0) {
2211 mbedtls_printf(" AES-CTR-128 (%s): ",
2212 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2213 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002214
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002215 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2216 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002217
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002218 offset = 0;
2219 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2220 goto exit;
2221 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002222
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002223 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002224
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002225 if (mode == MBEDTLS_AES_DECRYPT) {
2226 memcpy(buf, aes_test_ctr_ct[u], len);
2227 aes_tests = aes_test_ctr_pt[u];
2228 } else {
2229 memcpy(buf, aes_test_ctr_pt[u], len);
2230 aes_tests = aes_test_ctr_ct[u];
2231 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002232
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002233 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2234 stream_block, buf, buf);
2235 if (ret != 0) {
2236 goto exit;
2237 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002238
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002239 if (memcmp(buf, aes_tests, len) != 0) {
2240 ret = 1;
2241 goto exit;
2242 }
2243
2244 if (verbose != 0) {
2245 mbedtls_printf("passed\n");
2246 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002248 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002249
Gilles Peskine449bd832023-01-11 14:50:10 +01002250 if (verbose != 0) {
2251 mbedtls_printf("\n");
2252 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002253#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002254
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002255#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002256 /*
2257 * XTS mode
2258 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002259 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002260 static const int num_tests =
2261 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2262 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002263
Gilles Peskine449bd832023-01-11 14:50:10 +01002264 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002265
Gilles Peskine449bd832023-01-11 14:50:10 +01002266 for (i = 0; i < num_tests << 1; i++) {
2267 const unsigned char *data_unit;
2268 u = i >> 1;
2269 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002270
Gilles Peskine449bd832023-01-11 14:50:10 +01002271 if (verbose != 0) {
2272 mbedtls_printf(" AES-XTS-128 (%s): ",
2273 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2274 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002275
Gilles Peskine449bd832023-01-11 14:50:10 +01002276 memset(key, 0, sizeof(key));
2277 memcpy(key, aes_test_xts_key[u], 32);
2278 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002279
Gilles Peskine449bd832023-01-11 14:50:10 +01002280 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002281
Gilles Peskine449bd832023-01-11 14:50:10 +01002282 if (mode == MBEDTLS_AES_DECRYPT) {
2283 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2284 if (ret != 0) {
2285 goto exit;
2286 }
2287 memcpy(buf, aes_test_xts_ct32[u], len);
2288 aes_tests = aes_test_xts_pt32[u];
2289 } else {
2290 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2291 if (ret != 0) {
2292 goto exit;
2293 }
2294 memcpy(buf, aes_test_xts_pt32[u], len);
2295 aes_tests = aes_test_xts_ct32[u];
2296 }
2297
2298
2299 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2300 buf, buf);
2301 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002302 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002303 }
2304
2305 if (memcmp(buf, aes_tests, len) != 0) {
2306 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002307 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002308 }
2309
2310 if (verbose != 0) {
2311 mbedtls_printf("passed\n");
2312 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002313 }
2314
Gilles Peskine449bd832023-01-11 14:50:10 +01002315 if (verbose != 0) {
2316 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002317 }
2318
Gilles Peskine449bd832023-01-11 14:50:10 +01002319 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002320 }
2321#endif /* MBEDTLS_CIPHER_MODE_XTS */
2322
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002323 ret = 0;
2324
2325exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002326 if (ret != 0 && verbose != 0) {
2327 mbedtls_printf("failed\n");
2328 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002329
Gilles Peskine449bd832023-01-11 14:50:10 +01002330 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002331
Gilles Peskine449bd832023-01-11 14:50:10 +01002332 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002333}
2334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002335#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002336
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002337#endif /* MBEDTLS_AES_C */