blob: c9610f59da2786895e0eb2cc01307926ce97e5a1 [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 Yu72fd0bd2023-08-18 16:31:01 +080037#if defined(MBEDTLS_ARCH_IS_ARM64)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yue62ff092023-08-16 14:15:00 +080043#if defined(__amd64__) || defined(__x86_64__) || \
Jerry Yu372f7a02023-08-18 17:26:25 +080044 ((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))
Jerry Yu02b15192023-04-23 14:43:19 +080045#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080046#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080047#endif
48#endif
49
Jerry Yue62ff092023-08-16 14:15:00 +080050#if defined(__i386__) || defined(_M_IX86)
51#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
52#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080053#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080054
Jerry Yu61fc5ed2023-08-18 17:28:48 +080055#if defined(MBEDTLS_PADLOCK_C)
56#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080057#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
58#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080059#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
60#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
61 "MBEDTLS_PADLOCK_C is set"
62#endif
63#endif
Jerry Yu02b15192023-04-23 14:43:19 +080064#endif
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000067#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000068#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000070#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010071#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080072#if defined(MBEDTLS_AESCE_C)
73#include "aesce.h"
74#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000075
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000076#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020079
Jerry Yu9e628622023-08-17 11:20:09 +080080#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000081static int aes_padlock_ace = -1;
82#endif
83
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000085/*
86 * Forward S-box
87 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010088#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
89 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000090static const unsigned char FSb[256] =
91{
92 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
93 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
94 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
95 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
96 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
97 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
98 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
99 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
100 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
101 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
102 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
103 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
104 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
105 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
106 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
107 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
108 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
109 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
110 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
111 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
112 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
113 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
114 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
115 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
116 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
117 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
118 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
119 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
120 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
121 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
122 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
123 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
124};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100125#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
126 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000127
128/*
129 * Forward tables
130 */
131#define FT \
132\
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
134 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
135 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
136 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
137 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
138 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
139 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
140 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
141 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
142 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
143 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
144 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
145 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
146 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
147 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
148 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
149 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
150 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
151 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
152 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
153 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
154 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
155 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
156 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
157 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
158 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
159 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
160 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
161 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
162 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
163 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
164 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
165 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
166 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
167 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
168 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
169 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
170 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
171 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
172 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
173 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
174 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
175 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
176 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
177 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
178 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
179 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
180 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
181 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
182 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
183 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
184 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
185 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
186 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
187 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
188 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
189 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
190 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
191 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
192 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
193 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
194 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
195 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
196 V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100198#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100199#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000201#undef V
202
Hanno Beckerad049a92017-06-19 16:31:54 +0100203#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000206static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000207#undef V
208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000210static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000211#undef V
212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000215#undef V
216
Hanno Becker177d3cf2017-06-07 15:52:48 +0100217#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200218
Dave Rodgman1be24632023-06-29 12:01:24 +0100219#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
220
Paul Bakker5121ce52009-01-03 21:22:43 +0000221#undef FT
222
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100223#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000224/*
225 * Reverse S-box
226 */
227static const unsigned char RSb[256] =
228{
229 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
230 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
231 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
232 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
233 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
234 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
235 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
236 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
237 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
238 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
239 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
240 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
241 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
242 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
243 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
244 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
245 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
246 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
247 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
248 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
249 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
250 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
251 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
252 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
253 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
254 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
255 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
256 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
257 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
258 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
259 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
260 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
261};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100262#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264/*
265 * Reverse tables
266 */
267#define RT \
268\
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
270 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
271 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
272 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
273 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
274 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
275 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
276 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
277 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
278 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
279 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
280 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
281 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
282 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
283 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
284 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
285 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
286 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
287 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
288 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
289 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
290 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
291 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
292 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
293 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
294 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
295 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
296 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
297 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
298 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
299 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
300 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
301 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
302 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
303 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
304 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
305 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
306 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
307 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
308 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
309 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
310 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
311 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
312 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
313 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
314 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
315 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
316 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
317 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
318 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
319 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
320 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
321 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
322 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
323 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
324 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
325 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
326 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
327 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
328 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
329 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
330 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
331 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
332 V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100334#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000338#undef V
339
Hanno Beckerad049a92017-06-19 16:31:54 +0100340#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000343static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000344#undef V
345
Gilles Peskine449bd832023-01-11 14:50:10 +0100346#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000348#undef V
349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000352#undef V
353
Hanno Becker177d3cf2017-06-07 15:52:48 +0100354#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200355
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800356#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
357
Paul Bakker5121ce52009-01-03 21:22:43 +0000358#undef RT
359
Dave Rodgman34152a42023-06-27 18:31:24 +0100360#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000361/*
362 * Round constants
363 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000364static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000365{
366 0x00000001, 0x00000002, 0x00000004, 0x00000008,
367 0x00000010, 0x00000020, 0x00000040, 0x00000080,
368 0x0000001B, 0x00000036
369};
Dave Rodgman34152a42023-06-27 18:31:24 +0100370#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
374/*
375 * Forward S-box & tables
376 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100377#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
378 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000379static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100380#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
381 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100382#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200383static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100384#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200385static uint32_t FT1[256];
386static uint32_t FT2[256];
387static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100388#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100389#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
391/*
392 * Reverse S-box & tables
393 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100394#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000395static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100396#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100397
398#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000399static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100400#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000401static uint32_t RT1[256];
402static uint32_t RT2[256];
403static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100404#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100405#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
Dave Rodgman8c753f92023-06-27 18:16:13 +0100407#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000408/*
409 * Round constants
410 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000411static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
413/*
414 * Tables generation code
415 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100416#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
417#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
418#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420static int aes_init_done = 0;
421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000423{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800424 int i;
425 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800426 uint8_t pow[256];
427 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
429 /*
430 * compute pow and log tables over GF(2^8)
431 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000433 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800434 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800435 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 }
437
438 /*
439 * calculate the round constants
440 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800442 RCON[i] = x;
443 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 }
445
446 /*
447 * generate the forward and reverse S-boxes
448 */
449 FSb[0x00] = 0x63;
450 RSb[0x63] = 0x00;
451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 x = pow[255 - log[i]];
454
Yanray Wangfe944ce2023-06-26 18:16:01 +0800455 y = x; y = (y << 1) | (y >> 7);
456 x ^= y; y = (y << 1) | (y >> 7);
457 x ^= y; y = (y << 1) | (y >> 7);
458 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000459 x ^= y ^ 0x63;
460
Yanray Wangfe944ce2023-06-26 18:16:01 +0800461 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000462 RSb[x] = (unsigned char) i;
463 }
464
465 /*
466 * generate the forward and reverse tables
467 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000469 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800470 y = XTIME(x);
471 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 FT0[i] = ((uint32_t) y) ^
474 ((uint32_t) x << 8) ^
475 ((uint32_t) x << 16) ^
476 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Hanno Beckerad049a92017-06-19 16:31:54 +0100478#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 FT1[i] = ROTL8(FT0[i]);
480 FT2[i] = ROTL8(FT1[i]);
481 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100482#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
484 x = RSb[i];
485
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100486#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
488 ((uint32_t) MUL(0x09, x) << 8) ^
489 ((uint32_t) MUL(0x0D, x) << 16) ^
490 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Hanno Beckerad049a92017-06-19 16:31:54 +0100492#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 RT1[i] = ROTL8(RT0[i]);
494 RT2[i] = ROTL8(RT1[i]);
495 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100496#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100497#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 }
499}
500
Dave Rodgman8c753f92023-06-27 18:16:13 +0100501#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
502
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200503#undef ROTL8
504
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
Hanno Beckerad049a92017-06-19 16:31:54 +0100507#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200508
Gilles Peskine449bd832023-01-11 14:50:10 +0100509#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
510#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
511#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200512
513#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100514#define AES_RT1(idx) ROTL8(RT0[idx])
515#define AES_RT2(idx) ROTL16(RT0[idx])
516#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200517
518#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100519#define AES_FT1(idx) ROTL8(FT0[idx])
520#define AES_FT2(idx) ROTL16(FT0[idx])
521#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200522
Hanno Becker177d3cf2017-06-07 15:52:48 +0100523#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200524
525#define AES_RT0(idx) RT0[idx]
526#define AES_RT1(idx) RT1[idx]
527#define AES_RT2(idx) RT2[idx]
528#define AES_RT3(idx) RT3[idx]
529
530#define AES_FT0(idx) FT0[idx]
531#define AES_FT1(idx) FT1[idx]
532#define AES_FT2(idx) FT2[idx]
533#define AES_FT3(idx) FT3[idx]
534
Hanno Becker177d3cf2017-06-07 15:52:48 +0100535#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200538{
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200540}
541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200543{
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200545 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200549}
550
Jaeden Amero9366feb2018-05-29 18:55:17 +0100551#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100552void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100553{
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 mbedtls_aes_init(&ctx->crypt);
555 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100556}
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100559{
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100561 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 }
Simon Butcher5201e412018-12-06 17:40:14 +0000563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 mbedtls_aes_free(&ctx->crypt);
565 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100566}
567#endif /* MBEDTLS_CIPHER_MODE_XTS */
568
Gilles Peskine0de8f852023-03-16 17:14:59 +0100569/* Some implementations need the round keys to be aligned.
570 * Return an offset to be added to buf, such that (buf + offset) is
571 * correctly aligned.
572 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
573 * i.e. an offset of 1 means 4 bytes and so on.
574 */
Jerry Yu96084472023-08-17 18:10:45 +0800575#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100576 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100577#define MAY_NEED_TO_ALIGN
578#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100579
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100580#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
581 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100582static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
583{
584#if defined(MAY_NEED_TO_ALIGN)
585 int align_16_bytes = 0;
586
Jerry Yu9e628622023-08-17 11:20:09 +0800587#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100588 if (aes_padlock_ace == -1) {
589 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
590 }
591 if (aes_padlock_ace) {
592 align_16_bytes = 1;
593 }
594#endif
595
Gilles Peskine9c682e72023-03-16 17:21:33 +0100596#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100597 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
598 align_16_bytes = 1;
599 }
600#endif
601
602 if (align_16_bytes) {
603 /* These implementations needs 16-byte alignment
604 * for the round key array. */
605 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
606 if (delta == 0) {
607 return 0;
608 } else {
609 return 4 - delta; // 16 bytes = 4 uint32_t
610 }
611 }
612#else /* MAY_NEED_TO_ALIGN */
613 (void) buf;
614#endif /* MAY_NEED_TO_ALIGN */
615
616 return 0;
617}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100618#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
619 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100620
Paul Bakker5121ce52009-01-03 21:22:43 +0000621/*
622 * AES key schedule (encryption)
623 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200624#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100625int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
626 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000627{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000628 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800632#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 case 192: ctx->nr = 12; break;
634 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800635#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 }
638
Simon Butcher5201e412018-12-06 17:40:14 +0000639#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000641 aes_gen_tables();
642 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000643 }
644#endif
645
Gilles Peskine0de8f852023-03-16 17:14:59 +0100646 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100647 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100649#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
651 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
652 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100653#endif
654
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800655#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100656 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800657 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
658 }
659#endif
660
Jerry Yu29c91ba2023-08-04 11:02:04 +0800661#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800662 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 }
665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 case 10:
668
Jerry Yu3a0f0442023-08-17 17:06:21 +0800669 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
672 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
673 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
674 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
676 RK[5] = RK[1] ^ RK[4];
677 RK[6] = RK[2] ^ RK[5];
678 RK[7] = RK[3] ^ RK[6];
679 }
680 break;
681
Arto Kinnunen732ca322023-04-14 14:26:10 +0800682#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 case 12:
684
Jerry Yu3a0f0442023-08-17 17:06:21 +0800685 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000686 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
688 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
689 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
690 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
692 RK[7] = RK[1] ^ RK[6];
693 RK[8] = RK[2] ^ RK[7];
694 RK[9] = RK[3] ^ RK[8];
695 RK[10] = RK[4] ^ RK[9];
696 RK[11] = RK[5] ^ RK[10];
697 }
698 break;
699
700 case 14:
701
Jerry Yu3a0f0442023-08-17 17:06:21 +0800702 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
705 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
706 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
707 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
709 RK[9] = RK[1] ^ RK[8];
710 RK[10] = RK[2] ^ RK[9];
711 RK[11] = RK[3] ^ RK[10];
712
713 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
715 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
716 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
717 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000718
719 RK[13] = RK[5] ^ RK[12];
720 RK[14] = RK[6] ^ RK[13];
721 RK[15] = RK[7] ^ RK[14];
722 }
723 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800724#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000725 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800728#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000729}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200730#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
732/*
733 * AES key schedule (decryption)
734 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200735#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100736int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
737 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000738{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800739#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800740 uint32_t *SK;
741#endif
742 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000744 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800745
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Gilles Peskine0de8f852023-03-16 17:14:59 +0100749 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100750 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200752 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200754 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000756
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200757 ctx->nr = cty.nr;
758
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100759#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
761 mbedtls_aesni_inverse_key((unsigned char *) RK,
762 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200763 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100764 }
765#endif
766
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800767#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100768 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800769 mbedtls_aesce_inverse_key(
770 (unsigned char *) RK,
771 (const unsigned char *) (cty.buf + cty.rk_offset),
772 ctx->nr);
773 goto exit;
774 }
775#endif
776
Jerry Yu29c91ba2023-08-04 11:02:04 +0800777#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100778 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
780 *RK++ = *SK++;
781 *RK++ = *SK++;
782 *RK++ = *SK++;
783 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800784 SK -= 8;
785 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
786 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
788 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
789 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
790 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000791 }
792 }
793
794 *RK++ = *SK++;
795 *RK++ = *SK++;
796 *RK++ = *SK++;
797 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800798#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200799exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000803}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100804#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100805
806#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100807static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
808 unsigned int keybits,
809 const unsigned char **key1,
810 unsigned int *key1bits,
811 const unsigned char **key2,
812 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100813{
814 const unsigned int half_keybits = keybits / 2;
815 const unsigned int half_keybytes = half_keybits / 8;
816
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818 case 256: break;
819 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100821 }
822
823 *key1bits = half_keybits;
824 *key2bits = half_keybits;
825 *key1 = &key[0];
826 *key2 = &key[half_keybytes];
827
828 return 0;
829}
830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
832 const unsigned char *key,
833 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100834{
Janos Follath24eed8d2019-11-22 13:21:35 +0000835 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100836 const unsigned char *key1, *key2;
837 unsigned int key1bits, key2bits;
838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
840 &key2, &key2bits);
841 if (ret != 0) {
842 return ret;
843 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100844
845 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
847 if (ret != 0) {
848 return ret;
849 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100850
851 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100853}
854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
856 const unsigned char *key,
857 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100858{
Janos Follath24eed8d2019-11-22 13:21:35 +0000859 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100860 const unsigned char *key1, *key2;
861 unsigned int key1bits, key2bits;
862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
864 &key2, &key2bits);
865 if (ret != 0) {
866 return ret;
867 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100868
869 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
871 if (ret != 0) {
872 return ret;
873 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100874
875 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100877}
878#endif /* MBEDTLS_CIPHER_MODE_XTS */
879
Gilles Peskine449bd832023-01-11 14:50:10 +0100880#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100881 do \
882 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
884 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
885 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
886 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100887 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
889 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
890 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
891 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100892 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
894 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
895 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
896 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100897 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
899 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
900 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
901 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
902 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100905 do \
906 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
908 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
909 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
910 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100911 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
913 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
914 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
915 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100916 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
918 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
919 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
920 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100921 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
923 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
924 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
925 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
926 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000927
928/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200929 * AES-ECB block encryption
930 */
931#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100932int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
933 const unsigned char input[16],
934 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935{
936 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100937 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200939 uint32_t X[4];
940 uint32_t Y[4];
941 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
944 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
945 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
946 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
949 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]);
950 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 +0200951 }
952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 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 +0200954
Gilles Peskine5197c662020-08-26 17:03:24 +0200955 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
957 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
958 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
959 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200960
Gilles Peskine5197c662020-08-26 17:03:24 +0200961 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
965 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200966
Gilles Peskine5197c662020-08-26 17:03:24 +0200967 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
971 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200972
Gilles Peskine5197c662020-08-26 17:03:24 +0200973 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
975 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
977 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
980 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
981 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
982 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200987}
988#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
989
990/*
991 * AES-ECB block decryption
992 */
993#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100994int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
995 const unsigned char input[16],
996 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200997{
998 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100999 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001001 uint32_t X[4];
1002 uint32_t Y[4];
1003 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1006 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1007 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1008 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1011 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]);
1012 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 +02001013 }
1014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 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 +02001016
Gilles Peskine5197c662020-08-26 17:03:24 +02001017 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1019 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1020 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1021 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001022
Gilles Peskine5197c662020-08-26 17:03:24 +02001023 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1027 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001028
Gilles Peskine5197c662020-08-26 17:03:24 +02001029 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1033 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001034
Gilles Peskine5197c662020-08-26 17:03:24 +02001035 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1037 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1039 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1042 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1043 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1044 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001049}
1050#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1051
Gilles Peskine0de8f852023-03-16 17:14:59 +01001052#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001053/* VIA Padlock and our intrinsics-based implementation of AESNI require
1054 * the round keys to be aligned on a 16-byte boundary. We take care of this
1055 * before creating them, but the AES context may have moved (this can happen
1056 * if the library is called from a language with managed memory), and in later
1057 * calls it might have a different alignment with respect to 16-byte memory.
1058 * So we may need to realign.
1059 */
1060static void aes_maybe_realign(mbedtls_aes_context *ctx)
1061{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001062 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1063 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001064 memmove(ctx->buf + new_offset, // new address
1065 ctx->buf + ctx->rk_offset, // current address
1066 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1067 ctx->rk_offset = new_offset;
1068 }
1069}
1070#endif
1071
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001072/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001073 * AES-ECB block encryption/decryption
1074 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001075int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1076 int mode,
1077 const unsigned char input[16],
1078 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001079{
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001081 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001083
Gilles Peskine0de8f852023-03-16 17:14:59 +01001084#if defined(MAY_NEED_TO_ALIGN)
1085 aes_maybe_realign(ctx);
1086#endif
1087
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001088#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1090 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1091 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001092#endif
1093
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001094#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001095 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001096 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1097 }
1098#endif
1099
Jerry Yu9e628622023-08-17 11:20:09 +08001100#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001102 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001103 }
1104#endif
1105
Jerry Yu29c91ba2023-08-04 11:02:04 +08001106#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 if (mode == MBEDTLS_AES_ENCRYPT) {
1108 return mbedtls_internal_aes_encrypt(ctx, input, output);
1109 } else {
1110 return mbedtls_internal_aes_decrypt(ctx, input, output);
1111 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001112#endif
1113
Paul Bakker5121ce52009-01-03 21:22:43 +00001114}
1115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001116#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001117
Paul Bakker5121ce52009-01-03 21:22:43 +00001118/*
1119 * AES-CBC buffer encryption/decryption
1120 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001121int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1122 int mode,
1123 size_t length,
1124 unsigned char iv[16],
1125 const unsigned char *input,
1126 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001127{
Gilles Peskine7820a572021-07-07 21:08:28 +02001128 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001129 unsigned char temp[16];
1130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001132 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001134
Paul Elliott2ad93672023-08-11 11:07:06 +01001135 /* Nothing to do if length is zero. */
1136 if (length == 0) {
1137 return 0;
1138 }
1139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 if (length % 16) {
1141 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1142 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001143
Jerry Yu9e628622023-08-17 11:20:09 +08001144#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 if (aes_padlock_ace > 0) {
1146 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1147 return 0;
1148 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001149
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001150 // If padlock data misaligned, we just fall back to
1151 // unaccelerated mode
1152 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001153 }
1154#endif
1155
Dave Rodgman906c63c2023-06-14 17:53:51 +01001156 const unsigned char *ivp = iv;
1157
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 if (mode == MBEDTLS_AES_DECRYPT) {
1159 while (length > 0) {
1160 memcpy(temp, input, 16);
1161 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1162 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001163 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001165 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001166 * the result for the next block in CBC, and the cost of transferring that data from
1167 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001168 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001169
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001171
1172 input += 16;
1173 output += 16;
1174 length -= 16;
1175 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 } else {
1177 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001178 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1181 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001182 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001184 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001185
1186 input += 16;
1187 output += 16;
1188 length -= 16;
1189 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001190 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001191 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001192 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001193
Gilles Peskine7820a572021-07-07 21:08:28 +02001194exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001195 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001196}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001197#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001198
Aorimn5f778012016-06-09 23:22:58 +02001199#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001200
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001201typedef unsigned char mbedtls_be128[16];
1202
1203/*
1204 * GF(2^128) multiplication function
1205 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001206 * This function multiplies a field element by x in the polynomial field
1207 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001208 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001209 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001210 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001211#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001212MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001213#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001214static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001215 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001216{
1217 uint64_t a, b, ra, rb;
1218
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 a = MBEDTLS_GET_UINT64_LE(x, 0);
1220 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001221
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1223 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001224
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1226 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001227}
1228
Aorimn5f778012016-06-09 23:22:58 +02001229/*
1230 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001231 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001232 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001233 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001234 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001235#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001236MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001237#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001238int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1239 int mode,
1240 size_t length,
1241 const unsigned char data_unit[16],
1242 const unsigned char *input,
1243 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001244{
Janos Follath24eed8d2019-11-22 13:21:35 +00001245 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001246 size_t blocks = length / 16;
1247 size_t leftover = length % 16;
1248 unsigned char tweak[16];
1249 unsigned char prev_tweak[16];
1250 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001251
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001253 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001255
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001256 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001258 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 }
Aorimn5f778012016-06-09 23:22:58 +02001260
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001261 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001263 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 }
Aorimn5f778012016-06-09 23:22:58 +02001265
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1268 data_unit, tweak);
1269 if (ret != 0) {
1270 return ret;
1271 }
Aorimn5f778012016-06-09 23:22:58 +02001272
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001274 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275 /* We are on the last block in a decrypt operation that has
1276 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001277 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001278 * the leftovers and then update the current tweak for use on this,
1279 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 memcpy(prev_tweak, tweak, sizeof(tweak));
1281 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282 }
1283
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1287 if (ret != 0) {
1288 return ret;
1289 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001290
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001292
1293 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001295
1296 output += 16;
1297 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001298 }
1299
Gilles Peskine449bd832023-01-11 14:50:10 +01001300 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001301 /* If we are on the leftover bytes in a decrypt operation, we need to
1302 * use the previous tweak for these bytes (as saved in prev_tweak). */
1303 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001304
Jaeden Amerod82cd862018-04-28 15:02:45 +01001305 /* We are now on the final part of the data unit, which doesn't divide
1306 * evenly by 16. It's time for ciphertext stealing. */
1307 size_t i;
1308 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001309
Jaeden Amerod82cd862018-04-28 15:02:45 +01001310 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001311 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001313 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001314 }
Aorimn5f778012016-06-09 23:22:58 +02001315
Dave Rodgman069e7f42022-11-24 19:37:26 +00001316 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001318
Jaeden Amerod82cd862018-04-28 15:02:45 +01001319 /* Copy ciphertext bytes from the previous block for input in this
1320 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001321 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001322
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1324 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001325 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 }
Aorimn5f778012016-06-09 23:22:58 +02001327
Jaeden Amerod82cd862018-04-28 15:02:45 +01001328 /* Write the result back to the previous block, overriding the previous
1329 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001331 }
1332
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001334}
1335#endif /* MBEDTLS_CIPHER_MODE_XTS */
1336
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001337#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001338/*
1339 * AES-CFB128 buffer encryption/decryption
1340 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001341int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1342 int mode,
1343 size_t length,
1344 size_t *iv_off,
1345 unsigned char iv[16],
1346 const unsigned char *input,
1347 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001348{
Paul Bakker27fdf462011-06-09 13:55:13 +00001349 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001350 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001351 size_t n;
1352
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001354 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001355 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001356
1357 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001358
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 if (n > 15) {
1360 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1361 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001362
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 if (mode == MBEDTLS_AES_DECRYPT) {
1364 while (length--) {
1365 if (n == 0) {
1366 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1367 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001368 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001370 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001371
1372 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001374 iv[n] = (unsigned char) c;
1375
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001377 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 } else {
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
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001388
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001390 }
1391 }
1392
1393 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001394 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001395
Gilles Peskine7820a572021-07-07 21:08:28 +02001396exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001397 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001398}
Paul Bakker556efba2014-01-24 15:38:12 +01001399
1400/*
1401 * AES-CFB8 buffer encryption/decryption
1402 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001403int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1404 int mode,
1405 size_t length,
1406 unsigned char iv[16],
1407 const unsigned char *input,
1408 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001409{
Gilles Peskine7820a572021-07-07 21:08:28 +02001410 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001411 unsigned char c;
1412 unsigned char ov[17];
1413
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001415 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 }
1417 while (length--) {
1418 memcpy(ov, iv, 16);
1419 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1420 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001421 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 }
Paul Bakker556efba2014-01-24 15:38:12 +01001423
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001425 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001426 }
Paul Bakker556efba2014-01-24 15:38:12 +01001427
Gilles Peskine449bd832023-01-11 14:50:10 +01001428 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001429
Gilles Peskine449bd832023-01-11 14:50:10 +01001430 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001431 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001432 }
Paul Bakker556efba2014-01-24 15:38:12 +01001433
Gilles Peskine449bd832023-01-11 14:50:10 +01001434 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001435 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001436 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001437
Gilles Peskine7820a572021-07-07 21:08:28 +02001438exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001439 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001440}
Simon Butcher76a5b222018-04-22 22:57:27 +01001441#endif /* MBEDTLS_CIPHER_MODE_CFB */
1442
1443#if defined(MBEDTLS_CIPHER_MODE_OFB)
1444/*
1445 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1446 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001447int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1448 size_t length,
1449 size_t *iv_off,
1450 unsigned char iv[16],
1451 const unsigned char *input,
1452 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001453{
Simon Butcherad4e4932018-04-29 00:43:47 +01001454 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001455 size_t n;
1456
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001457 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001458
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 if (n > 15) {
1460 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1461 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001462
Gilles Peskine449bd832023-01-11 14:50:10 +01001463 while (length--) {
1464 if (n == 0) {
1465 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1466 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001467 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001468 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001469 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001470 *output++ = *input++ ^ iv[n];
1471
Gilles Peskine449bd832023-01-11 14:50:10 +01001472 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001473 }
1474
1475 *iv_off = n;
1476
Simon Butcherad4e4932018-04-29 00:43:47 +01001477exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001478 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001479}
1480#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483/*
1484 * AES-CTR buffer encryption/decryption
1485 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001486int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1487 size_t length,
1488 size_t *nc_off,
1489 unsigned char nonce_counter[16],
1490 unsigned char stream_block[16],
1491 const unsigned char *input,
1492 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001493{
Paul Bakker369e14b2012-04-18 14:16:09 +00001494 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001495 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001496 size_t n;
1497
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001498 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001499
Gilles Peskine449bd832023-01-11 14:50:10 +01001500 if (n > 0x0F) {
1501 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1502 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001503
Gilles Peskine449bd832023-01-11 14:50:10 +01001504 while (length--) {
1505 if (n == 0) {
1506 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1507 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001508 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001509 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001510
Gilles Peskine449bd832023-01-11 14:50:10 +01001511 for (i = 16; i > 0; i--) {
1512 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001513 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001514 }
1515 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001516 }
1517 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001518 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001519
Gilles Peskine449bd832023-01-11 14:50:10 +01001520 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001521 }
1522
1523 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001524 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001525
Gilles Peskine7820a572021-07-07 21:08:28 +02001526exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001527 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001528}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001529#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001530
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001531#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001532
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001533#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001534/*
1535 * AES test vectors from:
1536 *
1537 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1538 */
Yanray Wang62c99912023-05-11 11:06:53 +08001539static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001540{
1541 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1542 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001543#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001544 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1545 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1546 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1547 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001548#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001549};
1550
Yanray Wang62c99912023-05-11 11:06:53 +08001551static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001552{
1553 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1554 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001555#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001556 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1557 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1558 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1559 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001560#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001561};
1562
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001563#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001564static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001565{
1566 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1567 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001568#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001569 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1570 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1571 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1572 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001573#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001574};
1575
Yanray Wang62c99912023-05-11 11:06:53 +08001576static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001577{
1578 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1579 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001580#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001581 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1582 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1583 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1584 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001585#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001586};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001587#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001588
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001589#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001590/*
1591 * AES-CFB128 test vectors from:
1592 *
1593 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1594 */
Yanray Wang62c99912023-05-11 11:06:53 +08001595static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001596{
1597 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1598 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001599#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001600 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1601 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1602 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1603 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1604 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1605 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1606 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001607#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001608};
1609
1610static const unsigned char aes_test_cfb128_iv[16] =
1611{
1612 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1613 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1614};
1615
1616static const unsigned char aes_test_cfb128_pt[64] =
1617{
1618 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1619 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1620 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1621 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1622 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1623 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1624 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1625 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1626};
1627
Yanray Wang62c99912023-05-11 11:06:53 +08001628static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001629{
1630 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1631 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1632 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1633 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1634 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1635 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1636 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1637 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001638#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001639 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1640 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1641 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1642 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1643 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1644 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1645 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1646 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1647 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1648 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1649 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1650 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1651 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1652 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1653 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1654 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001655#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001656};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001657#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001658
Simon Butcherad4e4932018-04-29 00:43:47 +01001659#if defined(MBEDTLS_CIPHER_MODE_OFB)
1660/*
1661 * AES-OFB test vectors from:
1662 *
Simon Butcher5db13622018-06-04 22:11:25 +01001663 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001664 */
Yanray Wang62c99912023-05-11 11:06:53 +08001665static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001666{
1667 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1668 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001669#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001670 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1671 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1672 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1673 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1674 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1675 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1676 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001677#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001678};
1679
1680static const unsigned char aes_test_ofb_iv[16] =
1681{
1682 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1683 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1684};
1685
1686static const unsigned char aes_test_ofb_pt[64] =
1687{
1688 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1689 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1690 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1691 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1692 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1693 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1694 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1695 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1696};
1697
Yanray Wang62c99912023-05-11 11:06:53 +08001698static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001699{
1700 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1701 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1702 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1703 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1704 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1705 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1706 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1707 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001708#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001709 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1710 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1711 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1712 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1713 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1714 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1715 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1716 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1717 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1718 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1719 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1720 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1721 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1722 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1723 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1724 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001725#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001726};
1727#endif /* MBEDTLS_CIPHER_MODE_OFB */
1728
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001729#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001730/*
1731 * AES-CTR test vectors from:
1732 *
1733 * http://www.faqs.org/rfcs/rfc3686.html
1734 */
1735
Yanray Wang62c99912023-05-11 11:06:53 +08001736static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001737{
1738 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1739 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1740 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1741 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1742 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1743 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1744};
1745
Yanray Wang62c99912023-05-11 11:06:53 +08001746static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001747{
1748 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1750 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1751 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1752 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1753 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1754};
1755
Yanray Wang62c99912023-05-11 11:06:53 +08001756static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001757{
1758 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1759 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001760 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1761 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1762 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1763 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1764
1765 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1766 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1767 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1768 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1769 0x20, 0x21, 0x22, 0x23 }
1770};
1771
Yanray Wang62c99912023-05-11 11:06:53 +08001772static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001773{
1774 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1775 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1776 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1777 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1778 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1779 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1780 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1781 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1782 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1783 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1784 0x25, 0xB2, 0x07, 0x2F }
1785};
1786
1787static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001788{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001789#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001790
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001791#if defined(MBEDTLS_CIPHER_MODE_XTS)
1792/*
1793 * AES-XTS test vectors from:
1794 *
1795 * IEEE P1619/D16 Annex B
1796 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1797 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1798 */
1799static const unsigned char aes_test_xts_key[][32] =
1800{
1801 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1805 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1806 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1807 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1808 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1809 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1810 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1811 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1812 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1813};
1814
1815static const unsigned char aes_test_xts_pt32[][32] =
1816{
1817 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1822 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1823 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1824 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1825 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1826 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1827 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1828 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1829};
1830
1831static const unsigned char aes_test_xts_ct32[][32] =
1832{
1833 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1834 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1835 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1836 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1837 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1838 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1839 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1840 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1841 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1842 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1843 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1844 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1845};
1846
1847static const unsigned char aes_test_xts_data_unit[][16] =
1848{
Gilles Peskine449bd832023-01-11 14:50:10 +01001849 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1851 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1853 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1854 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001855};
1856
1857#endif /* MBEDTLS_CIPHER_MODE_XTS */
1858
Paul Bakker5121ce52009-01-03 21:22:43 +00001859/*
1860 * Checkup routine
1861 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001862int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001863{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001864 int ret = 0, i, j, u, mode;
1865 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001866 unsigned char key[32];
1867 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001868 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001869#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1870 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001871 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001872#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001873#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001874 unsigned char prv[16];
1875#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001876#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1877 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001878 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001879#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001880#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001881 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001882#endif
1883#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001884 unsigned char nonce_counter[16];
1885 unsigned char stream_block[16];
1886#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001887 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001888
Gilles Peskine449bd832023-01-11 14:50:10 +01001889 memset(key, 0, 32);
1890 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001891
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001892 if (verbose != 0) {
1893#if defined(MBEDTLS_AES_ALT)
1894 mbedtls_printf(" AES note: alternative implementation.\n");
1895#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001896#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001897#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001898 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001899#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001900 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001901#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001902#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001903#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001904 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1905 mbedtls_printf(" AES note: using AESNI.\n");
1906 } else
1907#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001908#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001909 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1910 mbedtls_printf(" AES note: using VIA Padlock.\n");
1911 } else
1912#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001913#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001914 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001915 mbedtls_printf(" AES note: using AESCE.\n");
1916 } else
1917#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001918 {
1919#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1920 mbedtls_printf(" AES note: built-in implementation.\n");
1921#endif
1922 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001923#endif /* MBEDTLS_AES_ALT */
1924 }
1925
Paul Bakker5121ce52009-01-03 21:22:43 +00001926 /*
1927 * ECB mode
1928 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001929 {
1930 static const int num_tests =
1931 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001932
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001933 for (i = 0; i < num_tests << 1; i++) {
1934 u = i >> 1;
1935 keybits = 128 + u * 64;
1936 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001937
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001938 if (verbose != 0) {
1939 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1940 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1941 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001942
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001943 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001944
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001945 if (mode == MBEDTLS_AES_DECRYPT) {
1946 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1947 aes_tests = aes_test_ecb_dec[u];
1948 } else {
1949 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1950 aes_tests = aes_test_ecb_enc[u];
1951 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001952
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001953 /*
1954 * AES-192 is an optional feature that may be unavailable when
1955 * there is an alternative underlying implementation i.e. when
1956 * MBEDTLS_AES_ALT is defined.
1957 */
1958 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1959 mbedtls_printf("skipped\n");
1960 continue;
1961 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001962 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001963 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001964
1965 for (j = 0; j < 10000; j++) {
1966 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1967 if (ret != 0) {
1968 goto exit;
1969 }
1970 }
1971
1972 if (memcmp(buf, aes_tests, 16) != 0) {
1973 ret = 1;
1974 goto exit;
1975 }
1976
1977 if (verbose != 0) {
1978 mbedtls_printf("passed\n");
1979 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001980 }
1981
Gilles Peskine449bd832023-01-11 14:50:10 +01001982 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001983 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001984 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001985 }
1986
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001987#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001988 /*
1989 * CBC mode
1990 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001991 {
1992 static const int num_tests =
1993 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001994
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001995 for (i = 0; i < num_tests << 1; i++) {
1996 u = i >> 1;
1997 keybits = 128 + u * 64;
1998 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001999
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002000 if (verbose != 0) {
2001 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2002 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002003 }
2004
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002005 memset(iv, 0, 16);
2006 memset(prv, 0, 16);
2007 memset(buf, 0, 16);
2008
2009 if (mode == MBEDTLS_AES_DECRYPT) {
2010 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2011 aes_tests = aes_test_cbc_dec[u];
2012 } else {
2013 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2014 aes_tests = aes_test_cbc_enc[u];
2015 }
2016
2017 /*
2018 * AES-192 is an optional feature that may be unavailable when
2019 * there is an alternative underlying implementation i.e. when
2020 * MBEDTLS_AES_ALT is defined.
2021 */
2022 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2023 mbedtls_printf("skipped\n");
2024 continue;
2025 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002026 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002027 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002028
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002029 for (j = 0; j < 10000; j++) {
2030 if (mode == MBEDTLS_AES_ENCRYPT) {
2031 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002032
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002033 memcpy(tmp, prv, 16);
2034 memcpy(prv, buf, 16);
2035 memcpy(buf, tmp, 16);
2036 }
2037
2038 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2039 if (ret != 0) {
2040 goto exit;
2041 }
2042
2043 }
2044
2045 if (memcmp(buf, aes_tests, 16) != 0) {
2046 ret = 1;
2047 goto exit;
2048 }
2049
2050 if (verbose != 0) {
2051 mbedtls_printf("passed\n");
2052 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002053 }
2054
Gilles Peskine449bd832023-01-11 14:50:10 +01002055 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002056 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002057 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002058 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002059#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002060
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002061#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 /*
2063 * CFB128 mode
2064 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002065 {
2066 static const int num_tests =
2067 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002068
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002069 for (i = 0; i < num_tests << 1; i++) {
2070 u = i >> 1;
2071 keybits = 128 + u * 64;
2072 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002073
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002074 if (verbose != 0) {
2075 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2076 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2077 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002078
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002079 memcpy(iv, aes_test_cfb128_iv, 16);
2080 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002081
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002082 offset = 0;
2083 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2084 /*
2085 * AES-192 is an optional feature that may be unavailable when
2086 * there is an alternative underlying implementation i.e. when
2087 * MBEDTLS_AES_ALT is defined.
2088 */
2089 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2090 mbedtls_printf("skipped\n");
2091 continue;
2092 } else if (ret != 0) {
2093 goto exit;
2094 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002095
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 if (mode == MBEDTLS_AES_DECRYPT) {
2097 memcpy(buf, aes_test_cfb128_ct[u], 64);
2098 aes_tests = aes_test_cfb128_pt;
2099 } else {
2100 memcpy(buf, aes_test_cfb128_pt, 64);
2101 aes_tests = aes_test_cfb128_ct[u];
2102 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002103
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002104 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2105 if (ret != 0) {
2106 goto exit;
2107 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002108
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002109 if (memcmp(buf, aes_tests, 64) != 0) {
2110 ret = 1;
2111 goto exit;
2112 }
2113
2114 if (verbose != 0) {
2115 mbedtls_printf("passed\n");
2116 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002117 }
2118
Gilles Peskine449bd832023-01-11 14:50:10 +01002119 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002120 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002121 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002122 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002123#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002124
Simon Butcherad4e4932018-04-29 00:43:47 +01002125#if defined(MBEDTLS_CIPHER_MODE_OFB)
2126 /*
2127 * OFB mode
2128 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002129 {
2130 static const int num_tests =
2131 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002132
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002133 for (i = 0; i < num_tests << 1; i++) {
2134 u = i >> 1;
2135 keybits = 128 + u * 64;
2136 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002137
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002138 if (verbose != 0) {
2139 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2140 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2141 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002142
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002143 memcpy(iv, aes_test_ofb_iv, 16);
2144 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002145
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002146 offset = 0;
2147 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2148 /*
2149 * AES-192 is an optional feature that may be unavailable when
2150 * there is an alternative underlying implementation i.e. when
2151 * MBEDTLS_AES_ALT is defined.
2152 */
2153 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2154 mbedtls_printf("skipped\n");
2155 continue;
2156 } else if (ret != 0) {
2157 goto exit;
2158 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002159
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002160 if (mode == MBEDTLS_AES_DECRYPT) {
2161 memcpy(buf, aes_test_ofb_ct[u], 64);
2162 aes_tests = aes_test_ofb_pt;
2163 } else {
2164 memcpy(buf, aes_test_ofb_pt, 64);
2165 aes_tests = aes_test_ofb_ct[u];
2166 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002167
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002168 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2169 if (ret != 0) {
2170 goto exit;
2171 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002172
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002173 if (memcmp(buf, aes_tests, 64) != 0) {
2174 ret = 1;
2175 goto exit;
2176 }
2177
2178 if (verbose != 0) {
2179 mbedtls_printf("passed\n");
2180 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002181 }
2182
Gilles Peskine449bd832023-01-11 14:50:10 +01002183 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002184 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002185 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002186 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002187#endif /* MBEDTLS_CIPHER_MODE_OFB */
2188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002189#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002190 /*
2191 * CTR mode
2192 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002193 {
2194 static const int num_tests =
2195 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002196
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002197 for (i = 0; i < num_tests << 1; i++) {
2198 u = i >> 1;
2199 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002200
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002201 if (verbose != 0) {
2202 mbedtls_printf(" AES-CTR-128 (%s): ",
2203 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2204 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002205
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002206 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2207 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002208
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002209 offset = 0;
2210 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2211 goto exit;
2212 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002213
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002214 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002215
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002216 if (mode == MBEDTLS_AES_DECRYPT) {
2217 memcpy(buf, aes_test_ctr_ct[u], len);
2218 aes_tests = aes_test_ctr_pt[u];
2219 } else {
2220 memcpy(buf, aes_test_ctr_pt[u], len);
2221 aes_tests = aes_test_ctr_ct[u];
2222 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002223
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002224 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2225 stream_block, buf, buf);
2226 if (ret != 0) {
2227 goto exit;
2228 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002229
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002230 if (memcmp(buf, aes_tests, len) != 0) {
2231 ret = 1;
2232 goto exit;
2233 }
2234
2235 if (verbose != 0) {
2236 mbedtls_printf("passed\n");
2237 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002238 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002239 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002240
Gilles Peskine449bd832023-01-11 14:50:10 +01002241 if (verbose != 0) {
2242 mbedtls_printf("\n");
2243 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002244#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002245
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002247 /*
2248 * XTS mode
2249 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002250 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002251 static const int num_tests =
2252 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2253 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002254
Gilles Peskine449bd832023-01-11 14:50:10 +01002255 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002256
Gilles Peskine449bd832023-01-11 14:50:10 +01002257 for (i = 0; i < num_tests << 1; i++) {
2258 const unsigned char *data_unit;
2259 u = i >> 1;
2260 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002261
Gilles Peskine449bd832023-01-11 14:50:10 +01002262 if (verbose != 0) {
2263 mbedtls_printf(" AES-XTS-128 (%s): ",
2264 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2265 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002266
Gilles Peskine449bd832023-01-11 14:50:10 +01002267 memset(key, 0, sizeof(key));
2268 memcpy(key, aes_test_xts_key[u], 32);
2269 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002270
Gilles Peskine449bd832023-01-11 14:50:10 +01002271 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002272
Gilles Peskine449bd832023-01-11 14:50:10 +01002273 if (mode == MBEDTLS_AES_DECRYPT) {
2274 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2275 if (ret != 0) {
2276 goto exit;
2277 }
2278 memcpy(buf, aes_test_xts_ct32[u], len);
2279 aes_tests = aes_test_xts_pt32[u];
2280 } else {
2281 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2282 if (ret != 0) {
2283 goto exit;
2284 }
2285 memcpy(buf, aes_test_xts_pt32[u], len);
2286 aes_tests = aes_test_xts_ct32[u];
2287 }
2288
2289
2290 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2291 buf, buf);
2292 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002293 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002294 }
2295
2296 if (memcmp(buf, aes_tests, len) != 0) {
2297 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002298 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002299 }
2300
2301 if (verbose != 0) {
2302 mbedtls_printf("passed\n");
2303 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002304 }
2305
Gilles Peskine449bd832023-01-11 14:50:10 +01002306 if (verbose != 0) {
2307 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002308 }
2309
Gilles Peskine449bd832023-01-11 14:50:10 +01002310 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002311 }
2312#endif /* MBEDTLS_CIPHER_MODE_XTS */
2313
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002314 ret = 0;
2315
2316exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002317 if (ret != 0 && verbose != 0) {
2318 mbedtls_printf("failed\n");
2319 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002320
Gilles Peskine449bd832023-01-11 14:50:10 +01002321 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002322
Gilles Peskine449bd832023-01-11 14:50:10 +01002323 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002324}
2325
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002326#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002328#endif /* MBEDTLS_AES_C */