blob: da0ab323932cea5ae3bf67775546fa91cae9e134 [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
Yanray Wangdbcc0c62023-08-30 15:04:01 +080078#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
79 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY))
80#define MBEDTLS_AES_NEED_FORWARD_S_BOXES
81#endif
82
83#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) && \
84 !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
85#define MBEDTLS_AES_NEED_REVERSE_TABLES
86#endif
87
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020089
Jerry Yu9e628622023-08-17 11:20:09 +080090#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000091static int aes_padlock_ace = -1;
92#endif
93
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020094#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000095/*
96 * Forward S-box
97 */
Yanray Wangdbcc0c62023-08-30 15:04:01 +080098#if defined(MBEDTLS_AES_NEED_FORWARD_S_BOXES)
Paul Bakker5121ce52009-01-03 21:22:43 +000099static const unsigned char FSb[256] =
100{
101 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
102 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
103 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
104 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
105 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
106 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
107 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
108 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
109 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
110 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
111 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
112 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
113 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
114 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
115 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
116 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
117 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
118 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
119 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
120 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
121 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
122 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
123 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
124 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
125 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
126 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
127 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
128 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
129 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
130 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
131 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
132 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
133};
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800134#endif /* MBEDTLS_AES_NEED_FORWARD_S_BOXES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000135
136/*
137 * Forward tables
138 */
139#define FT \
140\
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
142 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
143 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
144 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
145 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
146 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
147 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
148 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
149 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
150 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
151 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
152 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
153 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
154 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
155 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
156 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
157 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
158 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
159 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
160 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
161 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
162 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
163 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
164 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
165 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
166 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
167 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
168 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
169 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
170 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
171 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
172 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
173 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
174 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
175 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
176 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
177 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
178 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
179 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
180 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
181 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
182 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
183 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
184 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
185 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
186 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
187 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
188 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
189 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
190 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
191 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
192 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
193 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
194 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
195 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
196 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
197 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
198 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
199 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
200 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
201 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
202 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
203 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
204 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 +0000205
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100206#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100207#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000208static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000209#undef V
210
Hanno Beckerad049a92017-06-19 16:31:54 +0100211#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000215#undef V
216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000218static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000219#undef V
220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000222static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000223#undef V
224
Hanno Becker177d3cf2017-06-07 15:52:48 +0100225#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200226
Yanray Wang422a77f2023-07-07 10:12:05 +0800227#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
Dave Rodgman1be24632023-06-29 12:01:24 +0100228
Paul Bakker5121ce52009-01-03 21:22:43 +0000229#undef FT
230
Yanray Wang78ee0c92023-05-15 11:23:50 +0800231#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000232/*
233 * Reverse S-box
234 */
235static const unsigned char RSb[256] =
236{
237 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
238 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
239 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
240 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
241 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
242 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
243 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
244 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
245 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
246 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
247 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
248 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
249 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
250 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
251 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
252 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
253 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
254 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
255 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
256 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
257 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
258 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
259 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
260 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
261 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
262 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
263 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
264 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
265 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
266 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
267 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
268 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
269};
Yanray Wang78ee0c92023-05-15 11:23:50 +0800270#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000271
272/*
273 * Reverse tables
274 */
275#define RT \
276\
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
278 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
279 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
280 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
281 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
282 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
283 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
284 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
285 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
286 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
287 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
288 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
289 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
290 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
291 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
292 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
293 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
294 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
295 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
296 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
297 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
298 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
299 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
300 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
301 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
302 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
303 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
304 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
305 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
306 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
307 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
308 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
309 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
310 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
311 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
312 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
313 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
314 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
315 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
316 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
317 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
318 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
319 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
320 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
321 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
322 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
323 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
324 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
325 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
326 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
327 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
328 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
329 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
330 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
331 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
332 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
333 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
334 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
335 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
336 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
337 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
338 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
339 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
340 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 +0000341
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800342#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000346#undef V
347
Hanno Beckerad049a92017-06-19 16:31:54 +0100348#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000352#undef V
353
Gilles Peskine449bd832023-01-11 14:50:10 +0100354#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000356#undef V
357
Gilles Peskine449bd832023-01-11 14:50:10 +0100358#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000359static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000360#undef V
361
Hanno Becker177d3cf2017-06-07 15:52:48 +0100362#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800363#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800364
Paul Bakker5121ce52009-01-03 21:22:43 +0000365#undef RT
366
Dave Rodgman34152a42023-06-27 18:31:24 +0100367#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000368/*
369 * Round constants
370 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000371static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000372{
373 0x00000001, 0x00000002, 0x00000004, 0x00000008,
374 0x00000010, 0x00000020, 0x00000040, 0x00000080,
375 0x0000001B, 0x00000036
376};
Yanray Wang422a77f2023-07-07 10:12:05 +0800377#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000380
381/*
382 * Forward S-box & tables
383 */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800384#if defined(MBEDTLS_AES_NEED_FORWARD_S_BOXES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000385static unsigned char FSb[256];
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800386#endif
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100387#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200388static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100389#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200390static uint32_t FT1[256];
391static uint32_t FT2[256];
392static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100393#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang422a77f2023-07-07 10:12:05 +0800394#endif /* !MBEDTLS_AES_ENCRYPT_ALT || !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000395
396/*
397 * Reverse S-box & tables
398 */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800399#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
400#if (!defined(MBEDTLS_AES_SETKEY_ENC_ALT) && !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) || \
401 !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000402static unsigned char RSb[256];
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800403#endif
404#endif /* !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100405
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800406#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000407static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100408#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000409static uint32_t RT1[256];
410static uint32_t RT2[256];
411static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100412#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800413#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
Dave Rodgman8c753f92023-06-27 18:16:13 +0100415#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000416/*
417 * Round constants
418 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000419static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000420
421/*
422 * Tables generation code
423 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100424#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
425#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
426#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
428static int aes_init_done = 0;
429
Gilles Peskine449bd832023-01-11 14:50:10 +0100430static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000431{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800432 int i;
433 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800434 uint8_t pow[256];
435 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
437 /*
438 * compute pow and log tables over GF(2^8)
439 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800442 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800443 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 }
445
446 /*
447 * calculate the round constants
448 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800450 RCON[i] = x;
451 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 }
453
454 /*
455 * generate the forward and reverse S-boxes
456 */
457 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800458#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000459 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800460#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 x = pow[255 - log[i]];
464
Yanray Wangfe944ce2023-06-26 18:16:01 +0800465 y = x; y = (y << 1) | (y >> 7);
466 x ^= y; y = (y << 1) | (y >> 7);
467 x ^= y; y = (y << 1) | (y >> 7);
468 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000469 x ^= y ^ 0x63;
470
Yanray Wangfe944ce2023-06-26 18:16:01 +0800471 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800472#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000473 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800474#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000475 }
476
477 /*
478 * generate the forward and reverse tables
479 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000481 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800482 y = XTIME(x);
483 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 FT0[i] = ((uint32_t) y) ^
486 ((uint32_t) x << 8) ^
487 ((uint32_t) x << 16) ^
488 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
Hanno Beckerad049a92017-06-19 16:31:54 +0100490#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 FT1[i] = ROTL8(FT0[i]);
492 FT2[i] = ROTL8(FT1[i]);
493 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100494#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800496#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000497 x = RSb[i];
498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
500 ((uint32_t) MUL(0x09, x) << 8) ^
501 ((uint32_t) MUL(0x0D, x) << 16) ^
502 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000503
Hanno Beckerad049a92017-06-19 16:31:54 +0100504#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100505 RT1[i] = ROTL8(RT0[i]);
506 RT2[i] = ROTL8(RT1[i]);
507 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100508#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800509#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000510 }
511}
512
Yanray Wang422a77f2023-07-07 10:12:05 +0800513#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Dave Rodgman8c753f92023-06-27 18:16:13 +0100514
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200515#undef ROTL8
516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
Hanno Beckerad049a92017-06-19 16:31:54 +0100519#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200520
Gilles Peskine449bd832023-01-11 14:50:10 +0100521#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
522#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
523#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200524
525#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100526#define AES_RT1(idx) ROTL8(RT0[idx])
527#define AES_RT2(idx) ROTL16(RT0[idx])
528#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200529
530#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100531#define AES_FT1(idx) ROTL8(FT0[idx])
532#define AES_FT2(idx) ROTL16(FT0[idx])
533#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200534
Hanno Becker177d3cf2017-06-07 15:52:48 +0100535#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200536
537#define AES_RT0(idx) RT0[idx]
538#define AES_RT1(idx) RT1[idx]
539#define AES_RT2(idx) RT2[idx]
540#define AES_RT3(idx) RT3[idx]
541
542#define AES_FT0(idx) FT0[idx]
543#define AES_FT1(idx) FT1[idx]
544#define AES_FT2(idx) FT2[idx]
545#define AES_FT3(idx) FT3[idx]
546
Hanno Becker177d3cf2017-06-07 15:52:48 +0100547#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200550{
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200552}
553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200555{
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200557 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200559
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200561}
562
Jaeden Amero9366feb2018-05-29 18:55:17 +0100563#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100564void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100565{
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 mbedtls_aes_init(&ctx->crypt);
567 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100568}
569
Gilles Peskine449bd832023-01-11 14:50:10 +0100570void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100571{
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100573 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 }
Simon Butcher5201e412018-12-06 17:40:14 +0000575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 mbedtls_aes_free(&ctx->crypt);
577 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100578}
579#endif /* MBEDTLS_CIPHER_MODE_XTS */
580
Gilles Peskine0de8f852023-03-16 17:14:59 +0100581/* Some implementations need the round keys to be aligned.
582 * Return an offset to be added to buf, such that (buf + offset) is
583 * correctly aligned.
584 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
585 * i.e. an offset of 1 means 4 bytes and so on.
586 */
Jerry Yu96084472023-08-17 18:10:45 +0800587#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100588 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100589#define MAY_NEED_TO_ALIGN
590#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100591
Yanray Wang78ee0c92023-05-15 11:23:50 +0800592#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
593 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY))
Gilles Peskine0de8f852023-03-16 17:14:59 +0100594static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
595{
596#if defined(MAY_NEED_TO_ALIGN)
597 int align_16_bytes = 0;
598
Jerry Yu9e628622023-08-17 11:20:09 +0800599#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100600 if (aes_padlock_ace == -1) {
601 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
602 }
603 if (aes_padlock_ace) {
604 align_16_bytes = 1;
605 }
606#endif
607
Gilles Peskine9c682e72023-03-16 17:21:33 +0100608#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100609 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
610 align_16_bytes = 1;
611 }
612#endif
613
614 if (align_16_bytes) {
615 /* These implementations needs 16-byte alignment
616 * for the round key array. */
617 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
618 if (delta == 0) {
619 return 0;
620 } else {
621 return 4 - delta; // 16 bytes = 4 uint32_t
622 }
623 }
624#else /* MAY_NEED_TO_ALIGN */
625 (void) buf;
626#endif /* MAY_NEED_TO_ALIGN */
627
628 return 0;
629}
Yanray Wang78ee0c92023-05-15 11:23:50 +0800630#endif /* MAY_NEED_TO_ALIGN || !MBEDTLS_AES_SETKEY_ENC_ALT ||
631 (!MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100632
Paul Bakker5121ce52009-01-03 21:22:43 +0000633/*
634 * AES key schedule (encryption)
635 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200636#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100637int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
638 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000639{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000640 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000643 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800644#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000645 case 192: ctx->nr = 12; break;
646 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800647#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000649 }
650
Simon Butcher5201e412018-12-06 17:40:14 +0000651#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000653 aes_gen_tables();
654 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000655 }
656#endif
657
Gilles Peskine0de8f852023-03-16 17:14:59 +0100658 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100659 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100661#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
663 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
664 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100665#endif
666
Jerry Yu3f2fb712023-01-10 17:05:42 +0800667#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100668 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800669 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
670 }
671#endif
672
Jerry Yu29c91ba2023-08-04 11:02:04 +0800673#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800674 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000676 }
677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000679 case 10:
680
Jerry Yu3a0f0442023-08-17 17:06:21 +0800681 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000682 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
684 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
685 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
688 RK[5] = RK[1] ^ RK[4];
689 RK[6] = RK[2] ^ RK[5];
690 RK[7] = RK[3] ^ RK[6];
691 }
692 break;
693
Arto Kinnunen732ca322023-04-14 14:26:10 +0800694#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 case 12:
696
Jerry Yu3a0f0442023-08-17 17:06:21 +0800697 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000698 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
700 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
701 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
702 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000703
704 RK[7] = RK[1] ^ RK[6];
705 RK[8] = RK[2] ^ RK[7];
706 RK[9] = RK[3] ^ RK[8];
707 RK[10] = RK[4] ^ RK[9];
708 RK[11] = RK[5] ^ RK[10];
709 }
710 break;
711
712 case 14:
713
Jerry Yu3a0f0442023-08-17 17:06:21 +0800714 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000715 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
717 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
718 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
719 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000720
721 RK[9] = RK[1] ^ RK[8];
722 RK[10] = RK[2] ^ RK[9];
723 RK[11] = RK[3] ^ RK[10];
724
725 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
727 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
728 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
729 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
731 RK[13] = RK[5] ^ RK[12];
732 RK[14] = RK[6] ^ RK[13];
733 RK[15] = RK[7] ^ RK[14];
734 }
735 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800736#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000737 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800740#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000741}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200742#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000743
744/*
745 * AES key schedule (decryption)
746 */
Yanray Wang78ee0c92023-05-15 11:23:50 +0800747#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100748int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
749 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000750{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800751#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800752 uint32_t *SK;
753#endif
754 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000756 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800757
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200758
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000760
Gilles Peskine0de8f852023-03-16 17:14:59 +0100761 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100762 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000763
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200764 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200766 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000768
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200769 ctx->nr = cty.nr;
770
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100771#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
773 mbedtls_aesni_inverse_key((unsigned char *) RK,
774 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200775 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100776 }
777#endif
778
Jerry Yue096da12023-01-10 17:07:01 +0800779#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100780 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800781 mbedtls_aesce_inverse_key(
782 (unsigned char *) RK,
783 (const unsigned char *) (cty.buf + cty.rk_offset),
784 ctx->nr);
785 goto exit;
786 }
787#endif
788
Jerry Yu29c91ba2023-08-04 11:02:04 +0800789#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100790 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000791
792 *RK++ = *SK++;
793 *RK++ = *SK++;
794 *RK++ = *SK++;
795 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800796 SK -= 8;
797 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
798 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
800 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
801 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
802 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000803 }
804 }
805
806 *RK++ = *SK++;
807 *RK++ = *SK++;
808 *RK++ = *SK++;
809 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800810#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200811exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000815}
Yanray Wang78ee0c92023-05-15 11:23:50 +0800816#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100817
818#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100819static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
820 unsigned int keybits,
821 const unsigned char **key1,
822 unsigned int *key1bits,
823 const unsigned char **key2,
824 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100825{
826 const unsigned int half_keybits = keybits / 2;
827 const unsigned int half_keybytes = half_keybits / 8;
828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100830 case 256: break;
831 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100833 }
834
835 *key1bits = half_keybits;
836 *key2bits = half_keybits;
837 *key1 = &key[0];
838 *key2 = &key[half_keybytes];
839
840 return 0;
841}
842
Gilles Peskine449bd832023-01-11 14:50:10 +0100843int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
844 const unsigned char *key,
845 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100846{
Janos Follath24eed8d2019-11-22 13:21:35 +0000847 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100848 const unsigned char *key1, *key2;
849 unsigned int key1bits, key2bits;
850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
852 &key2, &key2bits);
853 if (ret != 0) {
854 return ret;
855 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100856
857 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
859 if (ret != 0) {
860 return ret;
861 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100862
863 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100865}
866
Gilles Peskine449bd832023-01-11 14:50:10 +0100867int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
868 const unsigned char *key,
869 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100870{
Janos Follath24eed8d2019-11-22 13:21:35 +0000871 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100872 const unsigned char *key1, *key2;
873 unsigned int key1bits, key2bits;
874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
876 &key2, &key2bits);
877 if (ret != 0) {
878 return ret;
879 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100880
881 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
883 if (ret != 0) {
884 return ret;
885 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100886
887 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100889}
890#endif /* MBEDTLS_CIPHER_MODE_XTS */
891
Gilles Peskine449bd832023-01-11 14:50:10 +0100892#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100893 do \
894 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
896 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
897 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
898 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100899 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
901 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
902 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
903 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100904 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
906 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
907 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
908 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100909 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
911 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
912 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
913 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
914 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000915
Gilles Peskine449bd832023-01-11 14:50:10 +0100916#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100917 do \
918 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
920 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
921 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
922 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100923 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
925 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
926 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
927 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100928 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
930 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
931 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
932 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100933 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
935 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
936 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
937 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
938 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000939
940/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200941 * AES-ECB block encryption
942 */
943#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100944int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
945 const unsigned char input[16],
946 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947{
948 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100949 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200951 uint32_t X[4];
952 uint32_t Y[4];
953 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
956 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
957 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
958 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
961 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]);
962 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 +0200963 }
964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 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 +0200966
Gilles Peskine5197c662020-08-26 17:03:24 +0200967 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
971 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200972
Gilles Peskine5197c662020-08-26 17:03:24 +0200973 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
975 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
977 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200978
Gilles Peskine5197c662020-08-26 17:03:24 +0200979 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
981 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
982 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
983 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200984
Gilles Peskine5197c662020-08-26 17:03:24 +0200985 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
987 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
988 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
989 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
992 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
993 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
994 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000995
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500997
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200999}
1000#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
1001
1002/*
1003 * AES-ECB block decryption
1004 */
Yanray Wang78ee0c92023-05-15 11:23:50 +08001005#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001006int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
1007 const unsigned char input[16],
1008 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001009{
1010 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +01001011 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001013 uint32_t X[4];
1014 uint32_t Y[4];
1015 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1018 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1019 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1020 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001021
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1023 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]);
1024 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 +02001025 }
1026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 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 +02001028
Gilles Peskine5197c662020-08-26 17:03:24 +02001029 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1033 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001034
Gilles Peskine5197c662020-08-26 17:03:24 +02001035 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1037 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1039 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001040
Gilles Peskine5197c662020-08-26 17:03:24 +02001041 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1043 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1044 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1045 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001046
Gilles Peskine5197c662020-08-26 17:03:24 +02001047 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1049 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1050 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1051 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1054 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1055 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1056 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001061}
Yanray Wang78ee0c92023-05-15 11:23:50 +08001062#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001063
Gilles Peskine0de8f852023-03-16 17:14:59 +01001064#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001065/* VIA Padlock and our intrinsics-based implementation of AESNI require
1066 * the round keys to be aligned on a 16-byte boundary. We take care of this
1067 * before creating them, but the AES context may have moved (this can happen
1068 * if the library is called from a language with managed memory), and in later
1069 * calls it might have a different alignment with respect to 16-byte memory.
1070 * So we may need to realign.
1071 */
1072static void aes_maybe_realign(mbedtls_aes_context *ctx)
1073{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001074 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1075 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001076 memmove(ctx->buf + new_offset, // new address
1077 ctx->buf + ctx->rk_offset, // current address
1078 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1079 ctx->rk_offset = new_offset;
1080 }
1081}
1082#endif
1083
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001084/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001085 * AES-ECB block encryption/decryption
1086 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001087int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1088 int mode,
1089 const unsigned char input[16],
1090 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001091{
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001093 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001095
Gilles Peskine0de8f852023-03-16 17:14:59 +01001096#if defined(MAY_NEED_TO_ALIGN)
1097 aes_maybe_realign(ctx);
1098#endif
1099
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001100#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1102 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1103 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001104#endif
1105
Jerry Yu2bb3d812023-01-10 17:38:26 +08001106#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001107 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001108 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1109 }
1110#endif
1111
Jerry Yu9e628622023-08-17 11:20:09 +08001112#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001114 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001115 }
1116#endif
1117
Jerry Yu29c91ba2023-08-04 11:02:04 +08001118#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001119#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 if (mode == MBEDTLS_AES_ENCRYPT) {
1121 return mbedtls_internal_aes_encrypt(ctx, input, output);
1122 } else {
1123 return mbedtls_internal_aes_decrypt(ctx, input, output);
1124 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001125#else
1126 return mbedtls_internal_aes_encrypt(ctx, input, output);
Jerry Yu29c91ba2023-08-04 11:02:04 +08001127#endif
Yanray Wang78ee0c92023-05-15 11:23:50 +08001128#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001129}
1130
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001131#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001132
Paul Bakker5121ce52009-01-03 21:22:43 +00001133/*
1134 * AES-CBC buffer encryption/decryption
1135 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001136int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1137 int mode,
1138 size_t length,
1139 unsigned char iv[16],
1140 const unsigned char *input,
1141 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001142{
Gilles Peskine7820a572021-07-07 21:08:28 +02001143 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001144 unsigned char temp[16];
1145
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001147 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001149
Paul Elliott2ad93672023-08-11 11:07:06 +01001150 /* Nothing to do if length is zero. */
1151 if (length == 0) {
1152 return 0;
1153 }
1154
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 if (length % 16) {
1156 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1157 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001158
Jerry Yu9e628622023-08-17 11:20:09 +08001159#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 if (aes_padlock_ace > 0) {
1161 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1162 return 0;
1163 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001164
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001165 // If padlock data misaligned, we just fall back to
1166 // unaccelerated mode
1167 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001168 }
1169#endif
1170
Dave Rodgman906c63c2023-06-14 17:53:51 +01001171 const unsigned char *ivp = iv;
1172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 if (mode == MBEDTLS_AES_DECRYPT) {
1174 while (length > 0) {
1175 memcpy(temp, input, 16);
1176 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1177 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001178 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001180 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001181 * the result for the next block in CBC, and the cost of transferring that data from
1182 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001183 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001184
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001186
1187 input += 16;
1188 output += 16;
1189 length -= 16;
1190 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 } else {
1192 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001193 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001194
Gilles Peskine449bd832023-01-11 14:50:10 +01001195 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1196 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001197 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001198 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001199 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001200
1201 input += 16;
1202 output += 16;
1203 length -= 16;
1204 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001205 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001206 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001207 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001208
Gilles Peskine7820a572021-07-07 21:08:28 +02001209exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001210 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001211}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001212#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001213
Aorimn5f778012016-06-09 23:22:58 +02001214#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001215
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001216typedef unsigned char mbedtls_be128[16];
1217
1218/*
1219 * GF(2^128) multiplication function
1220 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001221 * This function multiplies a field element by x in the polynomial field
1222 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001223 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001224 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001225 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001226#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001227MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001228#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001229static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001230 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001231{
1232 uint64_t a, b, ra, rb;
1233
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 a = MBEDTLS_GET_UINT64_LE(x, 0);
1235 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001236
Gilles Peskine449bd832023-01-11 14:50:10 +01001237 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1238 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001239
Gilles Peskine449bd832023-01-11 14:50:10 +01001240 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1241 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001242}
1243
Aorimn5f778012016-06-09 23:22:58 +02001244/*
1245 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001246 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001247 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001248 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001249 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001250#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001251MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001252#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001253int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1254 int mode,
1255 size_t length,
1256 const unsigned char data_unit[16],
1257 const unsigned char *input,
1258 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001259{
Janos Follath24eed8d2019-11-22 13:21:35 +00001260 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261 size_t blocks = length / 16;
1262 size_t leftover = length % 16;
1263 unsigned char tweak[16];
1264 unsigned char prev_tweak[16];
1265 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001266
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001268 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001270
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001271 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 }
Aorimn5f778012016-06-09 23:22:58 +02001275
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001276 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001278 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 }
Aorimn5f778012016-06-09 23:22:58 +02001280
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1283 data_unit, tweak);
1284 if (ret != 0) {
1285 return ret;
1286 }
Aorimn5f778012016-06-09 23:22:58 +02001287
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001289 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001290 /* We are on the last block in a decrypt operation that has
1291 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001292 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001293 * the leftovers and then update the current tweak for use on this,
1294 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 memcpy(prev_tweak, tweak, sizeof(tweak));
1296 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001297 }
1298
Gilles Peskine449bd832023-01-11 14:50:10 +01001299 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300
Gilles Peskine449bd832023-01-11 14:50:10 +01001301 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1302 if (ret != 0) {
1303 return ret;
1304 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001305
Gilles Peskine449bd832023-01-11 14:50:10 +01001306 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001307
1308 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001310
1311 output += 16;
1312 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001313 }
1314
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001316 /* If we are on the leftover bytes in a decrypt operation, we need to
1317 * use the previous tweak for these bytes (as saved in prev_tweak). */
1318 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001319
Jaeden Amerod82cd862018-04-28 15:02:45 +01001320 /* We are now on the final part of the data unit, which doesn't divide
1321 * evenly by 16. It's time for ciphertext stealing. */
1322 size_t i;
1323 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001324
Jaeden Amerod82cd862018-04-28 15:02:45 +01001325 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001326 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001328 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001329 }
Aorimn5f778012016-06-09 23:22:58 +02001330
Dave Rodgman069e7f42022-11-24 19:37:26 +00001331 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001333
Jaeden Amerod82cd862018-04-28 15:02:45 +01001334 /* Copy ciphertext bytes from the previous block for input in this
1335 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001336 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001337
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1339 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001340 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 }
Aorimn5f778012016-06-09 23:22:58 +02001342
Jaeden Amerod82cd862018-04-28 15:02:45 +01001343 /* Write the result back to the previous block, overriding the previous
1344 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001346 }
1347
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001349}
1350#endif /* MBEDTLS_CIPHER_MODE_XTS */
1351
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001352#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001353/*
1354 * AES-CFB128 buffer encryption/decryption
1355 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001356int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1357 int mode,
1358 size_t length,
1359 size_t *iv_off,
1360 unsigned char iv[16],
1361 const unsigned char *input,
1362 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001363{
Paul Bakker27fdf462011-06-09 13:55:13 +00001364 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001365 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001366 size_t n;
1367
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001369 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001370 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001371
1372 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001373
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 if (n > 15) {
1375 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1376 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001377
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 if (mode == MBEDTLS_AES_DECRYPT) {
1379 while (length--) {
1380 if (n == 0) {
1381 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1382 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001383 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001385 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001386
1387 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001389 iv[n] = (unsigned char) c;
1390
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001392 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 } else {
1394 while (length--) {
1395 if (n == 0) {
1396 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1397 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001398 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001399 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001400 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001401
Gilles Peskine449bd832023-01-11 14:50:10 +01001402 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001403
Gilles Peskine449bd832023-01-11 14:50:10 +01001404 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001405 }
1406 }
1407
1408 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001409 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001410
Gilles Peskine7820a572021-07-07 21:08:28 +02001411exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001412 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001413}
Paul Bakker556efba2014-01-24 15:38:12 +01001414
1415/*
1416 * AES-CFB8 buffer encryption/decryption
1417 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001418int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1419 int mode,
1420 size_t length,
1421 unsigned char iv[16],
1422 const unsigned char *input,
1423 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001424{
Gilles Peskine7820a572021-07-07 21:08:28 +02001425 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001426 unsigned char c;
1427 unsigned char ov[17];
1428
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001430 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001431 }
1432 while (length--) {
1433 memcpy(ov, iv, 16);
1434 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1435 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001436 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 }
Paul Bakker556efba2014-01-24 15:38:12 +01001438
Gilles Peskine449bd832023-01-11 14:50:10 +01001439 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001440 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001441 }
Paul Bakker556efba2014-01-24 15:38:12 +01001442
Gilles Peskine449bd832023-01-11 14:50:10 +01001443 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001444
Gilles Peskine449bd832023-01-11 14:50:10 +01001445 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001446 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001447 }
Paul Bakker556efba2014-01-24 15:38:12 +01001448
Gilles Peskine449bd832023-01-11 14:50:10 +01001449 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001450 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001451 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001452
Gilles Peskine7820a572021-07-07 21:08:28 +02001453exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001454 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001455}
Simon Butcher76a5b222018-04-22 22:57:27 +01001456#endif /* MBEDTLS_CIPHER_MODE_CFB */
1457
1458#if defined(MBEDTLS_CIPHER_MODE_OFB)
1459/*
1460 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1461 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001462int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1463 size_t length,
1464 size_t *iv_off,
1465 unsigned char iv[16],
1466 const unsigned char *input,
1467 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001468{
Simon Butcherad4e4932018-04-29 00:43:47 +01001469 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001470 size_t n;
1471
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001472 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001473
Gilles Peskine449bd832023-01-11 14:50:10 +01001474 if (n > 15) {
1475 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1476 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001477
Gilles Peskine449bd832023-01-11 14:50:10 +01001478 while (length--) {
1479 if (n == 0) {
1480 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1481 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001482 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001483 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001484 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001485 *output++ = *input++ ^ iv[n];
1486
Gilles Peskine449bd832023-01-11 14:50:10 +01001487 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001488 }
1489
1490 *iv_off = n;
1491
Simon Butcherad4e4932018-04-29 00:43:47 +01001492exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001493 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001494}
1495#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001498/*
1499 * AES-CTR buffer encryption/decryption
1500 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001501int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1502 size_t length,
1503 size_t *nc_off,
1504 unsigned char nonce_counter[16],
1505 unsigned char stream_block[16],
1506 const unsigned char *input,
1507 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001508{
Paul Bakker369e14b2012-04-18 14:16:09 +00001509 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001510 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001511 size_t n;
1512
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001513 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001514
Gilles Peskine449bd832023-01-11 14:50:10 +01001515 if (n > 0x0F) {
1516 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1517 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001518
Gilles Peskine449bd832023-01-11 14:50:10 +01001519 while (length--) {
1520 if (n == 0) {
1521 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1522 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001523 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001524 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001525
Gilles Peskine449bd832023-01-11 14:50:10 +01001526 for (i = 16; i > 0; i--) {
1527 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001528 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001529 }
1530 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001531 }
1532 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001533 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001534
Gilles Peskine449bd832023-01-11 14:50:10 +01001535 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001536 }
1537
1538 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001539 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001540
Gilles Peskine7820a572021-07-07 21:08:28 +02001541exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001542 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001543}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001544#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001545
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001546#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001547
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001548#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001549/*
1550 * AES test vectors from:
1551 *
1552 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1553 */
Yanray Wang78ee0c92023-05-15 11:23:50 +08001554#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Yanray Wang62c99912023-05-11 11:06:53 +08001555static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001556{
1557 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1558 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001559#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001560 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1561 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1562 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1563 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001564#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001565};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001566#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001567
Yanray Wang62c99912023-05-11 11:06:53 +08001568static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001569{
1570 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1571 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001572#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001573 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1574 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1575 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1576 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001577#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001578};
1579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001580#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001581static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001582{
1583 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1584 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001585#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001586 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1587 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1588 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1589 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001590#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001591};
1592
Yanray Wang62c99912023-05-11 11:06:53 +08001593static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001594{
1595 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1596 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001597#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001598 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1599 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1600 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1601 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001602#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001603};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001604#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001605
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001606#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001607/*
1608 * AES-CFB128 test vectors from:
1609 *
1610 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1611 */
Yanray Wang62c99912023-05-11 11:06:53 +08001612static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001613{
1614 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1615 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001616#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001617 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1618 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1619 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1620 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1621 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1622 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1623 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001624#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001625};
1626
1627static const unsigned char aes_test_cfb128_iv[16] =
1628{
1629 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1630 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1631};
1632
1633static const unsigned char aes_test_cfb128_pt[64] =
1634{
1635 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1636 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1637 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1638 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1639 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1640 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1641 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1642 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1643};
1644
Yanray Wang62c99912023-05-11 11:06:53 +08001645static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001646{
1647 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1648 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1649 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1650 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1651 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1652 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1653 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1654 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001655#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001656 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1657 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1658 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1659 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1660 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1661 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1662 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1663 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1664 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1665 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1666 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1667 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1668 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1669 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1670 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1671 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001672#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001673};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001674#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001675
Simon Butcherad4e4932018-04-29 00:43:47 +01001676#if defined(MBEDTLS_CIPHER_MODE_OFB)
1677/*
1678 * AES-OFB test vectors from:
1679 *
Simon Butcher5db13622018-06-04 22:11:25 +01001680 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001681 */
Yanray Wang62c99912023-05-11 11:06:53 +08001682static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001683{
1684 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1685 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001686#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001687 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1688 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1689 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1690 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1691 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1692 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1693 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001694#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001695};
1696
1697static const unsigned char aes_test_ofb_iv[16] =
1698{
1699 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1700 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1701};
1702
1703static const unsigned char aes_test_ofb_pt[64] =
1704{
1705 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1706 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1707 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1708 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1709 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1710 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1711 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1712 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1713};
1714
Yanray Wang62c99912023-05-11 11:06:53 +08001715static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001716{
1717 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1718 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1719 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1720 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1721 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1722 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1723 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1724 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001725#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001726 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1727 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1728 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1729 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1730 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1731 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1732 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1733 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1734 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1735 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1736 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1737 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1738 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1739 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1740 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1741 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001742#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001743};
1744#endif /* MBEDTLS_CIPHER_MODE_OFB */
1745
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001746#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001747/*
1748 * AES-CTR test vectors from:
1749 *
1750 * http://www.faqs.org/rfcs/rfc3686.html
1751 */
1752
Yanray Wang62c99912023-05-11 11:06:53 +08001753static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001754{
1755 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1756 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1757 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1758 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1759 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1760 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1761};
1762
Yanray Wang62c99912023-05-11 11:06:53 +08001763static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001764{
1765 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1767 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1768 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1769 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1770 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1771};
1772
Yanray Wang62c99912023-05-11 11:06:53 +08001773static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001774{
1775 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1776 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001777 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1778 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1779 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1780 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1781
1782 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1783 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1784 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1785 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1786 0x20, 0x21, 0x22, 0x23 }
1787};
1788
Yanray Wang62c99912023-05-11 11:06:53 +08001789static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001790{
1791 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1792 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1793 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1794 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1795 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1796 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1797 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1798 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1799 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1800 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1801 0x25, 0xB2, 0x07, 0x2F }
1802};
1803
1804static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001805{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001806#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001807
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001808#if defined(MBEDTLS_CIPHER_MODE_XTS)
1809/*
1810 * AES-XTS test vectors from:
1811 *
1812 * IEEE P1619/D16 Annex B
1813 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1814 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1815 */
1816static const unsigned char aes_test_xts_key[][32] =
1817{
1818 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1821 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1822 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1823 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1824 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1825 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1826 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1827 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1828 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1829 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1830};
1831
1832static const unsigned char aes_test_xts_pt32[][32] =
1833{
1834 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1838 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1839 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1840 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1841 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1842 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1843 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1844 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1845 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1846};
1847
1848static const unsigned char aes_test_xts_ct32[][32] =
1849{
1850 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1851 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1852 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1853 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1854 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1855 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1856 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1857 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1858 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1859 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1860 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1861 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1862};
1863
1864static const unsigned char aes_test_xts_data_unit[][16] =
1865{
Gilles Peskine449bd832023-01-11 14:50:10 +01001866 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1868 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1870 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001872};
1873
1874#endif /* MBEDTLS_CIPHER_MODE_XTS */
1875
Paul Bakker5121ce52009-01-03 21:22:43 +00001876/*
1877 * Checkup routine
1878 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001879int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001880{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001881 int ret = 0, i, j, u, mode;
1882 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001883 unsigned char key[32];
1884 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001885 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001886#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1887 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001888 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001889#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001890#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001891 unsigned char prv[16];
1892#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001893#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1894 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001895 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001896#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001897#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001898 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001899#endif
1900#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001901 unsigned char nonce_counter[16];
1902 unsigned char stream_block[16];
1903#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001904 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001905
Gilles Peskine449bd832023-01-11 14:50:10 +01001906 memset(key, 0, 32);
1907 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001908
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001909 if (verbose != 0) {
1910#if defined(MBEDTLS_AES_ALT)
1911 mbedtls_printf(" AES note: alternative implementation.\n");
1912#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001913#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001914#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001915 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001916#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001917 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001918#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001919#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001920#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001921 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1922 mbedtls_printf(" AES note: using AESNI.\n");
1923 } else
1924#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001925#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001926 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1927 mbedtls_printf(" AES note: using VIA Padlock.\n");
1928 } else
1929#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001930#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001931 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001932 mbedtls_printf(" AES note: using AESCE.\n");
1933 } else
1934#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001935 {
1936#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1937 mbedtls_printf(" AES note: built-in implementation.\n");
1938#endif
1939 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001940#endif /* MBEDTLS_AES_ALT */
1941 }
1942
Paul Bakker5121ce52009-01-03 21:22:43 +00001943 /*
1944 * ECB mode
1945 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001946 {
1947 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001948 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001949
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001950 for (i = 0; i < num_tests << 1; i++) {
1951 u = i >> 1;
1952 keybits = 128 + u * 64;
1953 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001954
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001955 if (verbose != 0) {
1956 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1957 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1958 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001959#if defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
1960 if (mode == MBEDTLS_AES_DECRYPT) {
1961 if (verbose != 0) {
1962 mbedtls_printf("skipped\n");
1963 }
1964 continue;
1965 }
1966#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001967
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001968 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001969
Yanray Wang78ee0c92023-05-15 11:23:50 +08001970#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001971 if (mode == MBEDTLS_AES_DECRYPT) {
1972 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1973 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001974 } else
1975#endif
1976 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001977 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1978 aes_tests = aes_test_ecb_enc[u];
1979 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001980
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001981 /*
1982 * AES-192 is an optional feature that may be unavailable when
1983 * there is an alternative underlying implementation i.e. when
1984 * MBEDTLS_AES_ALT is defined.
1985 */
1986 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1987 mbedtls_printf("skipped\n");
1988 continue;
1989 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001990 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001991 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001992
1993 for (j = 0; j < 10000; j++) {
1994 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1995 if (ret != 0) {
1996 goto exit;
1997 }
1998 }
1999
2000 if (memcmp(buf, aes_tests, 16) != 0) {
2001 ret = 1;
2002 goto exit;
2003 }
2004
2005 if (verbose != 0) {
2006 mbedtls_printf("passed\n");
2007 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002008 }
2009
Gilles Peskine449bd832023-01-11 14:50:10 +01002010 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002011 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002013 }
2014
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002015#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002016 /*
2017 * CBC mode
2018 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002019 {
2020 static const int num_tests =
2021 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00002022
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002023 for (i = 0; i < num_tests << 1; i++) {
2024 u = i >> 1;
2025 keybits = 128 + u * 64;
2026 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01002027
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002028 if (verbose != 0) {
2029 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2030 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002031 }
2032
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002033 memset(iv, 0, 16);
2034 memset(prv, 0, 16);
2035 memset(buf, 0, 16);
2036
2037 if (mode == MBEDTLS_AES_DECRYPT) {
2038 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2039 aes_tests = aes_test_cbc_dec[u];
2040 } else {
2041 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2042 aes_tests = aes_test_cbc_enc[u];
2043 }
2044
2045 /*
2046 * AES-192 is an optional feature that may be unavailable when
2047 * there is an alternative underlying implementation i.e. when
2048 * MBEDTLS_AES_ALT is defined.
2049 */
2050 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2051 mbedtls_printf("skipped\n");
2052 continue;
2053 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002054 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002055 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002056
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002057 for (j = 0; j < 10000; j++) {
2058 if (mode == MBEDTLS_AES_ENCRYPT) {
2059 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002060
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002061 memcpy(tmp, prv, 16);
2062 memcpy(prv, buf, 16);
2063 memcpy(buf, tmp, 16);
2064 }
2065
2066 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2067 if (ret != 0) {
2068 goto exit;
2069 }
2070
2071 }
2072
2073 if (memcmp(buf, aes_tests, 16) != 0) {
2074 ret = 1;
2075 goto exit;
2076 }
2077
2078 if (verbose != 0) {
2079 mbedtls_printf("passed\n");
2080 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002081 }
2082
Gilles Peskine449bd832023-01-11 14:50:10 +01002083 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002084 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002085 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002086 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002087#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002090 /*
2091 * CFB128 mode
2092 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002093 {
2094 static const int num_tests =
2095 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002096
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002097 for (i = 0; i < num_tests << 1; i++) {
2098 u = i >> 1;
2099 keybits = 128 + u * 64;
2100 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002101
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002102 if (verbose != 0) {
2103 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2104 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2105 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002106
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002107 memcpy(iv, aes_test_cfb128_iv, 16);
2108 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002109
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002110 offset = 0;
2111 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2112 /*
2113 * AES-192 is an optional feature that may be unavailable when
2114 * there is an alternative underlying implementation i.e. when
2115 * MBEDTLS_AES_ALT is defined.
2116 */
2117 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2118 mbedtls_printf("skipped\n");
2119 continue;
2120 } else if (ret != 0) {
2121 goto exit;
2122 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002123
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002124 if (mode == MBEDTLS_AES_DECRYPT) {
2125 memcpy(buf, aes_test_cfb128_ct[u], 64);
2126 aes_tests = aes_test_cfb128_pt;
2127 } else {
2128 memcpy(buf, aes_test_cfb128_pt, 64);
2129 aes_tests = aes_test_cfb128_ct[u];
2130 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002131
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002132 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2133 if (ret != 0) {
2134 goto exit;
2135 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002136
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002137 if (memcmp(buf, aes_tests, 64) != 0) {
2138 ret = 1;
2139 goto exit;
2140 }
2141
2142 if (verbose != 0) {
2143 mbedtls_printf("passed\n");
2144 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002145 }
2146
Gilles Peskine449bd832023-01-11 14:50:10 +01002147 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002148 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002149 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002150 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002152
Simon Butcherad4e4932018-04-29 00:43:47 +01002153#if defined(MBEDTLS_CIPHER_MODE_OFB)
2154 /*
2155 * OFB mode
2156 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002157 {
2158 static const int num_tests =
2159 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002160
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002161 for (i = 0; i < num_tests << 1; i++) {
2162 u = i >> 1;
2163 keybits = 128 + u * 64;
2164 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002165
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002166 if (verbose != 0) {
2167 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2168 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2169 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002170
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002171 memcpy(iv, aes_test_ofb_iv, 16);
2172 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002173
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002174 offset = 0;
2175 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2176 /*
2177 * AES-192 is an optional feature that may be unavailable when
2178 * there is an alternative underlying implementation i.e. when
2179 * MBEDTLS_AES_ALT is defined.
2180 */
2181 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2182 mbedtls_printf("skipped\n");
2183 continue;
2184 } else if (ret != 0) {
2185 goto exit;
2186 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002187
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002188 if (mode == MBEDTLS_AES_DECRYPT) {
2189 memcpy(buf, aes_test_ofb_ct[u], 64);
2190 aes_tests = aes_test_ofb_pt;
2191 } else {
2192 memcpy(buf, aes_test_ofb_pt, 64);
2193 aes_tests = aes_test_ofb_ct[u];
2194 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2197 if (ret != 0) {
2198 goto exit;
2199 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002200
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002201 if (memcmp(buf, aes_tests, 64) != 0) {
2202 ret = 1;
2203 goto exit;
2204 }
2205
2206 if (verbose != 0) {
2207 mbedtls_printf("passed\n");
2208 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002209 }
2210
Gilles Peskine449bd832023-01-11 14:50:10 +01002211 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002212 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002213 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002214 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002215#endif /* MBEDTLS_CIPHER_MODE_OFB */
2216
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002217#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002218 /*
2219 * CTR mode
2220 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002221 {
2222 static const int num_tests =
2223 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002224
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002225 for (i = 0; i < num_tests << 1; i++) {
2226 u = i >> 1;
2227 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002228
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002229 if (verbose != 0) {
2230 mbedtls_printf(" AES-CTR-128 (%s): ",
2231 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2232 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002233
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002234 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2235 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002236
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002237 offset = 0;
2238 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2239 goto exit;
2240 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002241
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002242 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002243
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002244 if (mode == MBEDTLS_AES_DECRYPT) {
2245 memcpy(buf, aes_test_ctr_ct[u], len);
2246 aes_tests = aes_test_ctr_pt[u];
2247 } else {
2248 memcpy(buf, aes_test_ctr_pt[u], len);
2249 aes_tests = aes_test_ctr_ct[u];
2250 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002251
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002252 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2253 stream_block, buf, buf);
2254 if (ret != 0) {
2255 goto exit;
2256 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002257
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002258 if (memcmp(buf, aes_tests, len) != 0) {
2259 ret = 1;
2260 goto exit;
2261 }
2262
2263 if (verbose != 0) {
2264 mbedtls_printf("passed\n");
2265 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002266 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002267 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002268
Gilles Peskine449bd832023-01-11 14:50:10 +01002269 if (verbose != 0) {
2270 mbedtls_printf("\n");
2271 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002272#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002273
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002274#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002275 /*
2276 * XTS mode
2277 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002278 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002279 static const int num_tests =
2280 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2281 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002282
Gilles Peskine449bd832023-01-11 14:50:10 +01002283 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002284
Gilles Peskine449bd832023-01-11 14:50:10 +01002285 for (i = 0; i < num_tests << 1; i++) {
2286 const unsigned char *data_unit;
2287 u = i >> 1;
2288 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002289
Gilles Peskine449bd832023-01-11 14:50:10 +01002290 if (verbose != 0) {
2291 mbedtls_printf(" AES-XTS-128 (%s): ",
2292 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2293 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002294
Gilles Peskine449bd832023-01-11 14:50:10 +01002295 memset(key, 0, sizeof(key));
2296 memcpy(key, aes_test_xts_key[u], 32);
2297 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002298
Gilles Peskine449bd832023-01-11 14:50:10 +01002299 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002300
Gilles Peskine449bd832023-01-11 14:50:10 +01002301 if (mode == MBEDTLS_AES_DECRYPT) {
2302 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2303 if (ret != 0) {
2304 goto exit;
2305 }
2306 memcpy(buf, aes_test_xts_ct32[u], len);
2307 aes_tests = aes_test_xts_pt32[u];
2308 } else {
2309 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2310 if (ret != 0) {
2311 goto exit;
2312 }
2313 memcpy(buf, aes_test_xts_pt32[u], len);
2314 aes_tests = aes_test_xts_ct32[u];
2315 }
2316
2317
2318 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2319 buf, buf);
2320 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002321 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002322 }
2323
2324 if (memcmp(buf, aes_tests, len) != 0) {
2325 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002326 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002327 }
2328
2329 if (verbose != 0) {
2330 mbedtls_printf("passed\n");
2331 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002332 }
2333
Gilles Peskine449bd832023-01-11 14:50:10 +01002334 if (verbose != 0) {
2335 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002336 }
2337
Gilles Peskine449bd832023-01-11 14:50:10 +01002338 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002339 }
2340#endif /* MBEDTLS_CIPHER_MODE_XTS */
2341
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002342 ret = 0;
2343
2344exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002345 if (ret != 0 && verbose != 0) {
2346 mbedtls_printf("failed\n");
2347 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002348
Gilles Peskine449bd832023-01-11 14:50:10 +01002349 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002350
Gilles Peskine449bd832023-01-11 14:50:10 +01002351 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002352}
2353
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002354#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002356#endif /* MBEDTLS_AES_C */