blob: d6ecdcca507c28385d6d7cefae60018986d15fd3 [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 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * 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
37#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
38 defined(__aarch64__) && !defined(MBEDTLS_HAVE_ARM64)
39#define MBEDTLS_HAVE_ARM64
40#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
41#error "MBEDTLS_AES_C defined, but not all prerequisites"
42#endif
43#endif
44
45#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
46 (defined(__amd64__) || defined(__x86_64__)) && \
47 !defined(MBEDTLS_HAVE_X86_64)
48#define MBEDTLS_HAVE_X86_64
49#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
50#error "MBEDTLS_AES_C defined, but not all prerequisites"
51#endif
52#endif
53
54#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \
55 !defined(MBEDTLS_HAVE_ASAN)
56#define MBEDTLS_HAVE_X86
57
58#if !defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
59#error "MBEDTLS_AES_C defined, but not all prerequisites"
60#endif
61#endif
62
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000064#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000065#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000067#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010068#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080069#if defined(MBEDTLS_AESCE_C)
70#include "aesce.h"
71#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000072
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000073#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010074
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020076
Gilles Peskine0f454e42023-03-16 14:58:46 +010077#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000078static int aes_padlock_ace = -1;
79#endif
80
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000082/*
83 * Forward S-box
84 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010085#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
86 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000087static const unsigned char FSb[256] =
88{
89 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
90 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
91 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
92 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
93 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
94 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
95 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
96 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
97 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
98 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
99 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
100 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
101 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
102 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
103 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
104 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
105 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
106 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
107 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
108 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
109 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
110 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
111 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
112 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
113 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
114 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
115 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
116 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
117 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
118 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
119 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
120 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
121};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100122#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
123 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000124
125/*
126 * Forward tables
127 */
128#define FT \
129\
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
131 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
132 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
133 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
134 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
135 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
136 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
137 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
138 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
139 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
140 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
141 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
142 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
143 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
144 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
145 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
146 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
147 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
148 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
149 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
150 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
151 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
152 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
153 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
154 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
155 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
156 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
157 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
158 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
159 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
160 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
161 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
162 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
163 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
164 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
165 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
166 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
167 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
168 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
169 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
170 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
171 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
172 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
173 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
174 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
175 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
176 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
177 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
178 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
179 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
180 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
181 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
182 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
183 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
184 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
185 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
186 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
187 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
188 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
189 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
190 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
191 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
192 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
193 V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100195#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100196#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000197static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000198#undef V
199
Hanno Beckerad049a92017-06-19 16:31:54 +0100200#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000203static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000204#undef V
205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000207static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000208#undef V
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000211static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000212#undef V
213
Hanno Becker177d3cf2017-06-07 15:52:48 +0100214#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200215
Dave Rodgman1be24632023-06-29 12:01:24 +0100216#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
217
Paul Bakker5121ce52009-01-03 21:22:43 +0000218#undef FT
219
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100220#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000221/*
222 * Reverse S-box
223 */
224static const unsigned char RSb[256] =
225{
226 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
227 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
228 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
229 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
230 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
231 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
232 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
233 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
234 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
235 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
236 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
237 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
238 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
239 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
240 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
241 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
242 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
243 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
244 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
245 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
246 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
247 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
248 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
249 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
250 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
251 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
252 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
253 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
254 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
255 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
256 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
257 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
258};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100259#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
261/*
262 * Reverse tables
263 */
264#define RT \
265\
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
267 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
268 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
269 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
270 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
271 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
272 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
273 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
274 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
275 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
276 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
277 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
278 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
279 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
280 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
281 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
282 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
283 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
284 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
285 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
286 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
287 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
288 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
289 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
290 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
291 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
292 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
293 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
294 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
295 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
296 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
297 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
298 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
299 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
300 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
301 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
302 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
303 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
304 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
305 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
306 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
307 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
308 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
309 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
310 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
311 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
312 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
313 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
314 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
315 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
316 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
317 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
318 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
319 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
320 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
321 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
322 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
323 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
324 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
325 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
326 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
327 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
328 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
329 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 +0000330
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100331#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000335#undef V
336
Hanno Beckerad049a92017-06-19 16:31:54 +0100337#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000340static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000341#undef V
342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000344static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000345#undef V
346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000349#undef V
350
Hanno Becker177d3cf2017-06-07 15:52:48 +0100351#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200352
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800353#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
354
Paul Bakker5121ce52009-01-03 21:22:43 +0000355#undef RT
356
Dave Rodgman34152a42023-06-27 18:31:24 +0100357#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000358/*
359 * Round constants
360 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000361static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000362{
363 0x00000001, 0x00000002, 0x00000004, 0x00000008,
364 0x00000010, 0x00000020, 0x00000040, 0x00000080,
365 0x0000001B, 0x00000036
366};
Dave Rodgman34152a42023-06-27 18:31:24 +0100367#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
371/*
372 * Forward S-box & tables
373 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100374#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
375 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000376static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100377#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
378 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100379#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200380static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100381#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200382static uint32_t FT1[256];
383static uint32_t FT2[256];
384static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100385#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100386#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
388/*
389 * Reverse S-box & tables
390 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100391#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000392static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100393#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100394
395#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000396static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100397#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000398static uint32_t RT1[256];
399static uint32_t RT2[256];
400static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100401#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100402#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
Dave Rodgman8c753f92023-06-27 18:16:13 +0100404#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000405/*
406 * Round constants
407 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000408static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410/*
411 * Tables generation code
412 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100413#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
414#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
415#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
417static int aes_init_done = 0;
418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000420{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800421 int i;
422 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800423 uint8_t pow[256];
424 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
426 /*
427 * compute pow and log tables over GF(2^8)
428 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800431 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800432 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000433 }
434
435 /*
436 * calculate the round constants
437 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800439 RCON[i] = x;
440 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 }
442
443 /*
444 * generate the forward and reverse S-boxes
445 */
446 FSb[0x00] = 0x63;
447 RSb[0x63] = 0x00;
448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 x = pow[255 - log[i]];
451
Yanray Wangfe944ce2023-06-26 18:16:01 +0800452 y = x; y = (y << 1) | (y >> 7);
453 x ^= y; y = (y << 1) | (y >> 7);
454 x ^= y; y = (y << 1) | (y >> 7);
455 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 x ^= y ^ 0x63;
457
Yanray Wangfe944ce2023-06-26 18:16:01 +0800458 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000459 RSb[x] = (unsigned char) i;
460 }
461
462 /*
463 * generate the forward and reverse tables
464 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800467 y = XTIME(x);
468 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 FT0[i] = ((uint32_t) y) ^
471 ((uint32_t) x << 8) ^
472 ((uint32_t) x << 16) ^
473 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
Hanno Beckerad049a92017-06-19 16:31:54 +0100475#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 FT1[i] = ROTL8(FT0[i]);
477 FT2[i] = ROTL8(FT1[i]);
478 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100479#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 x = RSb[i];
482
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100483#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
485 ((uint32_t) MUL(0x09, x) << 8) ^
486 ((uint32_t) MUL(0x0D, x) << 16) ^
487 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
Hanno Beckerad049a92017-06-19 16:31:54 +0100489#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 RT1[i] = ROTL8(RT0[i]);
491 RT2[i] = ROTL8(RT1[i]);
492 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100493#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100494#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 }
496}
497
Dave Rodgman8c753f92023-06-27 18:16:13 +0100498#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
499
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200500#undef ROTL8
501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000503
Hanno Beckerad049a92017-06-19 16:31:54 +0100504#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
507#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
508#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200509
510#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100511#define AES_RT1(idx) ROTL8(RT0[idx])
512#define AES_RT2(idx) ROTL16(RT0[idx])
513#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200514
515#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100516#define AES_FT1(idx) ROTL8(FT0[idx])
517#define AES_FT2(idx) ROTL16(FT0[idx])
518#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200519
Hanno Becker177d3cf2017-06-07 15:52:48 +0100520#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200521
522#define AES_RT0(idx) RT0[idx]
523#define AES_RT1(idx) RT1[idx]
524#define AES_RT2(idx) RT2[idx]
525#define AES_RT3(idx) RT3[idx]
526
527#define AES_FT0(idx) FT0[idx]
528#define AES_FT1(idx) FT1[idx]
529#define AES_FT2(idx) FT2[idx]
530#define AES_FT3(idx) FT3[idx]
531
Hanno Becker177d3cf2017-06-07 15:52:48 +0100532#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200535{
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200537}
538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200540{
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200542 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200546}
547
Jaeden Amero9366feb2018-05-29 18:55:17 +0100548#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100549void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100550{
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 mbedtls_aes_init(&ctx->crypt);
552 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100553}
554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100556{
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100558 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 }
Simon Butcher5201e412018-12-06 17:40:14 +0000560
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 mbedtls_aes_free(&ctx->crypt);
562 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100563}
564#endif /* MBEDTLS_CIPHER_MODE_XTS */
565
Gilles Peskine0de8f852023-03-16 17:14:59 +0100566/* Some implementations need the round keys to be aligned.
567 * Return an offset to be added to buf, such that (buf + offset) is
568 * correctly aligned.
569 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
570 * i.e. an offset of 1 means 4 bytes and so on.
571 */
572#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100573 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100574#define MAY_NEED_TO_ALIGN
575#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100576
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100577#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
578 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100579static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
580{
581#if defined(MAY_NEED_TO_ALIGN)
582 int align_16_bytes = 0;
583
584#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
585 if (aes_padlock_ace == -1) {
586 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
587 }
588 if (aes_padlock_ace) {
589 align_16_bytes = 1;
590 }
591#endif
592
Gilles Peskine9c682e72023-03-16 17:21:33 +0100593#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100594 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
595 align_16_bytes = 1;
596 }
597#endif
598
599 if (align_16_bytes) {
600 /* These implementations needs 16-byte alignment
601 * for the round key array. */
602 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
603 if (delta == 0) {
604 return 0;
605 } else {
606 return 4 - delta; // 16 bytes = 4 uint32_t
607 }
608 }
609#else /* MAY_NEED_TO_ALIGN */
610 (void) buf;
611#endif /* MAY_NEED_TO_ALIGN */
612
613 return 0;
614}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100615#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
616 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100617
Paul Bakker5121ce52009-01-03 21:22:43 +0000618/*
619 * AES key schedule (encryption)
620 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200621#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100622int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
623 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000624{
Paul Bakker23986e52011-04-24 08:57:21 +0000625 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000626 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800630#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 case 192: ctx->nr = 12; break;
632 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800633#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 }
636
Simon Butcher5201e412018-12-06 17:40:14 +0000637#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000639 aes_gen_tables();
640 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000641 }
642#endif
643
Gilles Peskine0de8f852023-03-16 17:14:59 +0100644 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100645 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100647#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
649 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
650 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100651#endif
652
Jerry Yu3f2fb712023-01-10 17:05:42 +0800653#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
654 if (mbedtls_aesce_has_support()) {
655 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
656 }
657#endif
658
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 for (i = 0; i < (keybits >> 5); i++) {
660 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 }
662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 case 10:
665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
669 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
670 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
671 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000672
673 RK[5] = RK[1] ^ RK[4];
674 RK[6] = RK[2] ^ RK[5];
675 RK[7] = RK[3] ^ RK[6];
676 }
677 break;
678
Arto Kinnunen732ca322023-04-14 14:26:10 +0800679#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000680 case 12:
681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
685 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
687 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
689 RK[7] = RK[1] ^ RK[6];
690 RK[8] = RK[2] ^ RK[7];
691 RK[9] = RK[3] ^ RK[8];
692 RK[10] = RK[4] ^ RK[9];
693 RK[11] = RK[5] ^ RK[10];
694 }
695 break;
696
697 case 14:
698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000700 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
702 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
703 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
704 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
706 RK[9] = RK[1] ^ RK[8];
707 RK[10] = RK[2] ^ RK[9];
708 RK[11] = RK[3] ^ RK[10];
709
710 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
712 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
713 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
714 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
716 RK[13] = RK[5] ^ RK[12];
717 RK[14] = RK[6] ^ RK[13];
718 RK[15] = RK[7] ^ RK[14];
719 }
720 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800721#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000722 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000725}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200726#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
728/*
729 * AES key schedule (decryption)
730 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200731#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100732int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
733 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000734{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200735 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000737 uint32_t *RK;
738 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200739
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000741
Gilles Peskine0de8f852023-03-16 17:14:59 +0100742 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100743 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000744
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200745 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200747 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000749
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200750 ctx->nr = cty.nr;
751
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100752#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
754 mbedtls_aesni_inverse_key((unsigned char *) RK,
755 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200756 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100757 }
758#endif
759
Jerry Yue096da12023-01-10 17:07:01 +0800760#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
761 if (mbedtls_aesce_has_support()) {
762 mbedtls_aesce_inverse_key(
763 (unsigned char *) RK,
764 (const unsigned char *) (cty.buf + cty.rk_offset),
765 ctx->nr);
766 goto exit;
767 }
768#endif
769
Werner Lewisdd76ef32022-05-30 12:00:21 +0100770 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
772 *RK++ = *SK++;
773 *RK++ = *SK++;
774 *RK++ = *SK++;
775 *RK++ = *SK++;
776
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
778 for (j = 0; j < 4; j++, SK++) {
779 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
780 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
781 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
782 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000783 }
784 }
785
786 *RK++ = *SK++;
787 *RK++ = *SK++;
788 *RK++ = *SK++;
789 *RK++ = *SK++;
790
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200791exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000793
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000795}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100796#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100797
798#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100799static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
800 unsigned int keybits,
801 const unsigned char **key1,
802 unsigned int *key1bits,
803 const unsigned char **key2,
804 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100805{
806 const unsigned int half_keybits = keybits / 2;
807 const unsigned int half_keybytes = half_keybits / 8;
808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100810 case 256: break;
811 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100813 }
814
815 *key1bits = half_keybits;
816 *key2bits = half_keybits;
817 *key1 = &key[0];
818 *key2 = &key[half_keybytes];
819
820 return 0;
821}
822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
824 const unsigned char *key,
825 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100826{
Janos Follath24eed8d2019-11-22 13:21:35 +0000827 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100828 const unsigned char *key1, *key2;
829 unsigned int key1bits, key2bits;
830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
832 &key2, &key2bits);
833 if (ret != 0) {
834 return ret;
835 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100836
837 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
839 if (ret != 0) {
840 return ret;
841 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100842
843 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100845}
846
Gilles Peskine449bd832023-01-11 14:50:10 +0100847int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
848 const unsigned char *key,
849 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100850{
Janos Follath24eed8d2019-11-22 13:21:35 +0000851 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100852 const unsigned char *key1, *key2;
853 unsigned int key1bits, key2bits;
854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
856 &key2, &key2bits);
857 if (ret != 0) {
858 return ret;
859 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100860
861 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
863 if (ret != 0) {
864 return ret;
865 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100866
867 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100869}
870#endif /* MBEDTLS_CIPHER_MODE_XTS */
871
Gilles Peskine449bd832023-01-11 14:50:10 +0100872#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100873 do \
874 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
876 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
877 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
878 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100879 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
881 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
882 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
883 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100884 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
886 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
887 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
888 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100889 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
891 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
892 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
893 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
894 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100897 do \
898 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
900 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
901 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
902 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100903 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
905 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
906 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
907 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100908 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
910 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
911 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
912 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100913 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
915 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
916 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
917 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
918 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000919
920/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200921 * AES-ECB block encryption
922 */
923#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100924int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
925 const unsigned char input[16],
926 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200927{
928 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100929 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200931 uint32_t X[4];
932 uint32_t Y[4];
933 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
936 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
937 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
938 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
941 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]);
942 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 +0200943 }
944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 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 +0200946
Gilles Peskine5197c662020-08-26 17:03:24 +0200947 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
949 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
950 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
951 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200952
Gilles Peskine5197c662020-08-26 17:03:24 +0200953 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
955 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
956 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
957 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200958
Gilles Peskine5197c662020-08-26 17:03:24 +0200959 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
961 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200964
Gilles Peskine5197c662020-08-26 17:03:24 +0200965 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
967 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200970
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
972 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
973 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
974 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500977
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200979}
980#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
981
982/*
983 * AES-ECB block decryption
984 */
985#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100986int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
987 const unsigned char input[16],
988 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200989{
990 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100991 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200993 uint32_t X[4];
994 uint32_t Y[4];
995 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
998 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
999 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1000 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1003 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]);
1004 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 +02001005 }
1006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 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 +02001008
Gilles Peskine5197c662020-08-26 17:03:24 +02001009 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1011 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1012 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1013 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001014
Gilles Peskine5197c662020-08-26 17:03:24 +02001015 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1017 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1018 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1019 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001020
Gilles Peskine5197c662020-08-26 17:03:24 +02001021 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1023 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001026
Gilles Peskine5197c662020-08-26 17:03:24 +02001027 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1029 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001032
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1034 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1035 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1036 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001041}
1042#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1043
Gilles Peskine0de8f852023-03-16 17:14:59 +01001044#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001045/* VIA Padlock and our intrinsics-based implementation of AESNI require
1046 * the round keys to be aligned on a 16-byte boundary. We take care of this
1047 * before creating them, but the AES context may have moved (this can happen
1048 * if the library is called from a language with managed memory), and in later
1049 * calls it might have a different alignment with respect to 16-byte memory.
1050 * So we may need to realign.
1051 */
1052static void aes_maybe_realign(mbedtls_aes_context *ctx)
1053{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001054 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1055 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001056 memmove(ctx->buf + new_offset, // new address
1057 ctx->buf + ctx->rk_offset, // current address
1058 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1059 ctx->rk_offset = new_offset;
1060 }
1061}
1062#endif
1063
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001064/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001065 * AES-ECB block encryption/decryption
1066 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001067int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1068 int mode,
1069 const unsigned char input[16],
1070 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001071{
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001073 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001075
Gilles Peskine0de8f852023-03-16 17:14:59 +01001076#if defined(MAY_NEED_TO_ALIGN)
1077 aes_maybe_realign(ctx);
1078#endif
1079
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001080#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1082 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1083 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001084#endif
1085
Jerry Yu2bb3d812023-01-10 17:38:26 +08001086#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1087 if (mbedtls_aesce_has_support()) {
1088 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1089 }
1090#endif
1091
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001092#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001094 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001095 }
1096#endif
1097
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 if (mode == MBEDTLS_AES_ENCRYPT) {
1099 return mbedtls_internal_aes_encrypt(ctx, input, output);
1100 } else {
1101 return mbedtls_internal_aes_decrypt(ctx, input, output);
1102 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001103}
1104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001105#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001106
Paul Bakker5121ce52009-01-03 21:22:43 +00001107/*
1108 * AES-CBC buffer encryption/decryption
1109 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001110int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1111 int mode,
1112 size_t length,
1113 unsigned char iv[16],
1114 const unsigned char *input,
1115 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001116{
Gilles Peskine7820a572021-07-07 21:08:28 +02001117 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001118 unsigned char temp[16];
1119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001121 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001123
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 if (length % 16) {
1125 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1126 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001127
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001128#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001129 if (aes_padlock_ace > 0) {
1130 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1131 return 0;
1132 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001133
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001134 // If padlock data misaligned, we just fall back to
1135 // unaccelerated mode
1136 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001137 }
1138#endif
1139
Dave Rodgman906c63c2023-06-14 17:53:51 +01001140 const unsigned char *ivp = iv;
1141
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 if (mode == MBEDTLS_AES_DECRYPT) {
1143 while (length > 0) {
1144 memcpy(temp, input, 16);
1145 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1146 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001147 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001149 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001150 * the result for the next block in CBC, and the cost of transferring that data from
1151 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001152 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001153
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001155
1156 input += 16;
1157 output += 16;
1158 length -= 16;
1159 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 } else {
1161 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001162 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001163
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1165 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001166 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001168 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001169
1170 input += 16;
1171 output += 16;
1172 length -= 16;
1173 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001174 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001175 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001176 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001177
Gilles Peskine7820a572021-07-07 21:08:28 +02001178exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001180}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001181#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001182
Aorimn5f778012016-06-09 23:22:58 +02001183#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001184
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001185typedef unsigned char mbedtls_be128[16];
1186
1187/*
1188 * GF(2^128) multiplication function
1189 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001190 * This function multiplies a field element by x in the polynomial field
1191 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001192 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001193 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001194 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001195#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001196MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001197#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001198static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001199 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001200{
1201 uint64_t a, b, ra, rb;
1202
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 a = MBEDTLS_GET_UINT64_LE(x, 0);
1204 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001205
Gilles Peskine449bd832023-01-11 14:50:10 +01001206 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1207 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001208
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1210 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001211}
1212
Aorimn5f778012016-06-09 23:22:58 +02001213/*
1214 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001215 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001216 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001217 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001218 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001219#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001220MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001221#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001222int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1223 int mode,
1224 size_t length,
1225 const unsigned char data_unit[16],
1226 const unsigned char *input,
1227 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001228{
Janos Follath24eed8d2019-11-22 13:21:35 +00001229 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001230 size_t blocks = length / 16;
1231 size_t leftover = length % 16;
1232 unsigned char tweak[16];
1233 unsigned char prev_tweak[16];
1234 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001235
Gilles Peskine449bd832023-01-11 14:50:10 +01001236 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001237 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001238 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001239
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001240 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001242 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001243 }
Aorimn5f778012016-06-09 23:22:58 +02001244
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001245 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001247 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 }
Aorimn5f778012016-06-09 23:22:58 +02001249
Jaeden Amerod82cd862018-04-28 15:02:45 +01001250 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1252 data_unit, tweak);
1253 if (ret != 0) {
1254 return ret;
1255 }
Aorimn5f778012016-06-09 23:22:58 +02001256
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001258 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001259 /* We are on the last block in a decrypt operation that has
1260 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001261 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 * the leftovers and then update the current tweak for use on this,
1263 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 memcpy(prev_tweak, tweak, sizeof(tweak));
1265 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 }
1267
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001269
Gilles Peskine449bd832023-01-11 14:50:10 +01001270 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1271 if (ret != 0) {
1272 return ret;
1273 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276
1277 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001279
1280 output += 16;
1281 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001282 }
1283
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285 /* If we are on the leftover bytes in a decrypt operation, we need to
1286 * use the previous tweak for these bytes (as saved in prev_tweak). */
1287 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001288
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289 /* We are now on the final part of the data unit, which doesn't divide
1290 * evenly by 16. It's time for ciphertext stealing. */
1291 size_t i;
1292 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001293
Jaeden Amerod82cd862018-04-28 15:02:45 +01001294 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001295 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001296 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001297 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001298 }
Aorimn5f778012016-06-09 23:22:58 +02001299
Dave Rodgman069e7f42022-11-24 19:37:26 +00001300 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001301 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001302
Jaeden Amerod82cd862018-04-28 15:02:45 +01001303 /* Copy ciphertext bytes from the previous block for input in this
1304 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001305 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001306
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1308 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001309 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 }
Aorimn5f778012016-06-09 23:22:58 +02001311
Jaeden Amerod82cd862018-04-28 15:02:45 +01001312 /* Write the result back to the previous block, overriding the previous
1313 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001315 }
1316
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001318}
1319#endif /* MBEDTLS_CIPHER_MODE_XTS */
1320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001322/*
1323 * AES-CFB128 buffer encryption/decryption
1324 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001325int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1326 int mode,
1327 size_t length,
1328 size_t *iv_off,
1329 unsigned char iv[16],
1330 const unsigned char *input,
1331 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001332{
Paul Bakker27fdf462011-06-09 13:55:13 +00001333 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001334 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001335 size_t n;
1336
Gilles Peskine449bd832023-01-11 14:50:10 +01001337 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001338 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001340
1341 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001342
Gilles Peskine449bd832023-01-11 14:50:10 +01001343 if (n > 15) {
1344 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1345 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001346
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 if (mode == MBEDTLS_AES_DECRYPT) {
1348 while (length--) {
1349 if (n == 0) {
1350 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1351 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001352 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001354 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001355
1356 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001357 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001358 iv[n] = (unsigned char) c;
1359
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 } else {
1363 while (length--) {
1364 if (n == 0) {
1365 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1366 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001367 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001369 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001370
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001372
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001374 }
1375 }
1376
1377 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001378 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001379
Gilles Peskine7820a572021-07-07 21:08:28 +02001380exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001382}
Paul Bakker556efba2014-01-24 15:38:12 +01001383
1384/*
1385 * AES-CFB8 buffer encryption/decryption
1386 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001387int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1388 int mode,
1389 size_t length,
1390 unsigned char iv[16],
1391 const unsigned char *input,
1392 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001393{
Gilles Peskine7820a572021-07-07 21:08:28 +02001394 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001395 unsigned char c;
1396 unsigned char ov[17];
1397
Gilles Peskine449bd832023-01-11 14:50:10 +01001398 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001399 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001400 }
1401 while (length--) {
1402 memcpy(ov, iv, 16);
1403 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1404 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001405 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001406 }
Paul Bakker556efba2014-01-24 15:38:12 +01001407
Gilles Peskine449bd832023-01-11 14:50:10 +01001408 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001409 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 }
Paul Bakker556efba2014-01-24 15:38:12 +01001411
Gilles Peskine449bd832023-01-11 14:50:10 +01001412 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001413
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001415 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 }
Paul Bakker556efba2014-01-24 15:38:12 +01001417
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001419 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001420 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001421
Gilles Peskine7820a572021-07-07 21:08:28 +02001422exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001424}
Simon Butcher76a5b222018-04-22 22:57:27 +01001425#endif /* MBEDTLS_CIPHER_MODE_CFB */
1426
1427#if defined(MBEDTLS_CIPHER_MODE_OFB)
1428/*
1429 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1430 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001431int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1432 size_t length,
1433 size_t *iv_off,
1434 unsigned char iv[16],
1435 const unsigned char *input,
1436 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001437{
Simon Butcherad4e4932018-04-29 00:43:47 +01001438 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001439 size_t n;
1440
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001441 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001442
Gilles Peskine449bd832023-01-11 14:50:10 +01001443 if (n > 15) {
1444 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1445 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001446
Gilles Peskine449bd832023-01-11 14:50:10 +01001447 while (length--) {
1448 if (n == 0) {
1449 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1450 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001451 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001452 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001453 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001454 *output++ = *input++ ^ iv[n];
1455
Gilles Peskine449bd832023-01-11 14:50:10 +01001456 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001457 }
1458
1459 *iv_off = n;
1460
Simon Butcherad4e4932018-04-29 00:43:47 +01001461exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001463}
1464#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001467/*
1468 * AES-CTR buffer encryption/decryption
1469 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001470int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1471 size_t length,
1472 size_t *nc_off,
1473 unsigned char nonce_counter[16],
1474 unsigned char stream_block[16],
1475 const unsigned char *input,
1476 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477{
Paul Bakker369e14b2012-04-18 14:16:09 +00001478 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001479 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001480 size_t n;
1481
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001482 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483
Gilles Peskine449bd832023-01-11 14:50:10 +01001484 if (n > 0x0F) {
1485 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1486 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001487
Gilles Peskine449bd832023-01-11 14:50:10 +01001488 while (length--) {
1489 if (n == 0) {
1490 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1491 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001492 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001493 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001494
Gilles Peskine449bd832023-01-11 14:50:10 +01001495 for (i = 16; i > 0; i--) {
1496 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001497 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001498 }
1499 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001500 }
1501 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001502 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001503
Gilles Peskine449bd832023-01-11 14:50:10 +01001504 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001505 }
1506
1507 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001508 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001509
Gilles Peskine7820a572021-07-07 21:08:28 +02001510exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001511 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001512}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001513#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001514
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001515#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001517#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001518/*
1519 * AES test vectors from:
1520 *
1521 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1522 */
Yanray Wang62c99912023-05-11 11:06:53 +08001523static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001524{
1525 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1526 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001527#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001528 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1529 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1530 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1531 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001532#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001533};
1534
Yanray Wang62c99912023-05-11 11:06:53 +08001535static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001536{
1537 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1538 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001539#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001540 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1541 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1542 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1543 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001544#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001545};
1546
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001547#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001548static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001549{
1550 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1551 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001552#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001553 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1554 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1555 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1556 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001557#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001558};
1559
Yanray Wang62c99912023-05-11 11:06:53 +08001560static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001561{
1562 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1563 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001564#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001565 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1566 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1567 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1568 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001569#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001570};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001571#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001572
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001573#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001574/*
1575 * AES-CFB128 test vectors from:
1576 *
1577 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1578 */
Yanray Wang62c99912023-05-11 11:06:53 +08001579static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001580{
1581 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1582 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001583#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001584 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1585 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1586 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1587 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1588 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1589 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1590 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001591#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001592};
1593
1594static const unsigned char aes_test_cfb128_iv[16] =
1595{
1596 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1597 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1598};
1599
1600static const unsigned char aes_test_cfb128_pt[64] =
1601{
1602 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1603 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1604 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1605 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1606 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1607 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1608 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1609 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1610};
1611
Yanray Wang62c99912023-05-11 11:06:53 +08001612static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001613{
1614 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1615 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1616 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1617 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1618 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1619 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1620 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1621 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001622#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001623 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1624 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1625 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1626 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1627 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1628 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1629 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1630 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1631 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1632 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1633 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1634 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1635 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1636 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1637 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1638 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001639#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001640};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001641#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001642
Simon Butcherad4e4932018-04-29 00:43:47 +01001643#if defined(MBEDTLS_CIPHER_MODE_OFB)
1644/*
1645 * AES-OFB test vectors from:
1646 *
Simon Butcher5db13622018-06-04 22:11:25 +01001647 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001648 */
Yanray Wang62c99912023-05-11 11:06:53 +08001649static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001650{
1651 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1652 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001653#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001654 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1655 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1656 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1657 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1658 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1659 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1660 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001661#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001662};
1663
1664static const unsigned char aes_test_ofb_iv[16] =
1665{
1666 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1667 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1668};
1669
1670static const unsigned char aes_test_ofb_pt[64] =
1671{
1672 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1673 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1674 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1675 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1676 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1677 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1678 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1679 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1680};
1681
Yanray Wang62c99912023-05-11 11:06:53 +08001682static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001683{
1684 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1685 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1686 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1687 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1688 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1689 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1690 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1691 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001692#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001693 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1694 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1695 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1696 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1697 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1698 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1699 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1700 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1701 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1702 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1703 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1704 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1705 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1706 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1707 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1708 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001709#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001710};
1711#endif /* MBEDTLS_CIPHER_MODE_OFB */
1712
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001713#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001714/*
1715 * AES-CTR test vectors from:
1716 *
1717 * http://www.faqs.org/rfcs/rfc3686.html
1718 */
1719
Yanray Wang62c99912023-05-11 11:06:53 +08001720static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001721{
1722 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1723 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1724 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1725 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1726 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1727 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1728};
1729
Yanray Wang62c99912023-05-11 11:06:53 +08001730static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001731{
1732 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1734 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1735 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1736 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1737 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1738};
1739
Yanray Wang62c99912023-05-11 11:06:53 +08001740static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001741{
1742 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1743 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001744 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1745 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1746 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1747 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1748
1749 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1750 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1751 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1752 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1753 0x20, 0x21, 0x22, 0x23 }
1754};
1755
Yanray Wang62c99912023-05-11 11:06:53 +08001756static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001757{
1758 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1759 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1760 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1761 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1762 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1763 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1764 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1765 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1766 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1767 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1768 0x25, 0xB2, 0x07, 0x2F }
1769};
1770
1771static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001772{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001773#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001774
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001775#if defined(MBEDTLS_CIPHER_MODE_XTS)
1776/*
1777 * AES-XTS test vectors from:
1778 *
1779 * IEEE P1619/D16 Annex B
1780 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1781 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1782 */
1783static const unsigned char aes_test_xts_key[][32] =
1784{
1785 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1787 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1788 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1789 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1790 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1791 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1792 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1793 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1794 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1795 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1796 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1797};
1798
1799static const unsigned char aes_test_xts_pt32[][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 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1806 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1807 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1808 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1809 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1810 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1811 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1812 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1813};
1814
1815static const unsigned char aes_test_xts_ct32[][32] =
1816{
1817 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1818 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1819 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1820 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1821 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1822 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1823 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1824 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1825 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1826 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1827 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1828 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1829};
1830
1831static const unsigned char aes_test_xts_data_unit[][16] =
1832{
Gilles Peskine449bd832023-01-11 14:50:10 +01001833 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1835 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1837 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001839};
1840
1841#endif /* MBEDTLS_CIPHER_MODE_XTS */
1842
Paul Bakker5121ce52009-01-03 21:22:43 +00001843/*
1844 * Checkup routine
1845 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001846int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001847{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001848 int ret = 0, i, j, u, mode;
1849 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001850 unsigned char key[32];
1851 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001852 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001853#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1854 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001855 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001856#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001857#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001858 unsigned char prv[16];
1859#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001860#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1861 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001862 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001863#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001864#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001865 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001866#endif
1867#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001868 unsigned char nonce_counter[16];
1869 unsigned char stream_block[16];
1870#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001871 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001872
Gilles Peskine449bd832023-01-11 14:50:10 +01001873 memset(key, 0, 32);
1874 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001876 if (verbose != 0) {
1877#if defined(MBEDTLS_AES_ALT)
1878 mbedtls_printf(" AES note: alternative implementation.\n");
1879#else /* MBEDTLS_AES_ALT */
1880#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1881 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1882 mbedtls_printf(" AES note: using VIA Padlock.\n");
1883 } else
1884#endif
1885#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001886#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001887 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001888#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001889 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001890#else
1891#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1892#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001893 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1894 mbedtls_printf(" AES note: using AESNI.\n");
1895 } else
1896#endif
1897#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1898 if (mbedtls_aesce_has_support()) {
1899 mbedtls_printf(" AES note: using AESCE.\n");
1900 } else
1901#endif
1902 mbedtls_printf(" AES note: built-in implementation.\n");
1903#endif /* MBEDTLS_AES_ALT */
1904 }
1905
Paul Bakker5121ce52009-01-03 21:22:43 +00001906 /*
1907 * ECB mode
1908 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001909 {
1910 static const int num_tests =
1911 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001912
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001913 for (i = 0; i < num_tests << 1; i++) {
1914 u = i >> 1;
1915 keybits = 128 + u * 64;
1916 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001917
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001918 if (verbose != 0) {
1919 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1920 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1921 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001922
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001923 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001924
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001925 if (mode == MBEDTLS_AES_DECRYPT) {
1926 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1927 aes_tests = aes_test_ecb_dec[u];
1928 } else {
1929 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1930 aes_tests = aes_test_ecb_enc[u];
1931 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001932
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001933 /*
1934 * AES-192 is an optional feature that may be unavailable when
1935 * there is an alternative underlying implementation i.e. when
1936 * MBEDTLS_AES_ALT is defined.
1937 */
1938 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1939 mbedtls_printf("skipped\n");
1940 continue;
1941 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001942 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001943 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001944
1945 for (j = 0; j < 10000; j++) {
1946 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1947 if (ret != 0) {
1948 goto exit;
1949 }
1950 }
1951
1952 if (memcmp(buf, aes_tests, 16) != 0) {
1953 ret = 1;
1954 goto exit;
1955 }
1956
1957 if (verbose != 0) {
1958 mbedtls_printf("passed\n");
1959 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001960 }
1961
Gilles Peskine449bd832023-01-11 14:50:10 +01001962 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001963 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001964 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001965 }
1966
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001967#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001968 /*
1969 * CBC mode
1970 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001971 {
1972 static const int num_tests =
1973 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001974
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001975 for (i = 0; i < num_tests << 1; i++) {
1976 u = i >> 1;
1977 keybits = 128 + u * 64;
1978 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001979
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001980 if (verbose != 0) {
1981 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1982 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001983 }
1984
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001985 memset(iv, 0, 16);
1986 memset(prv, 0, 16);
1987 memset(buf, 0, 16);
1988
1989 if (mode == MBEDTLS_AES_DECRYPT) {
1990 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1991 aes_tests = aes_test_cbc_dec[u];
1992 } else {
1993 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1994 aes_tests = aes_test_cbc_enc[u];
1995 }
1996
1997 /*
1998 * AES-192 is an optional feature that may be unavailable when
1999 * there is an alternative underlying implementation i.e. when
2000 * MBEDTLS_AES_ALT is defined.
2001 */
2002 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2003 mbedtls_printf("skipped\n");
2004 continue;
2005 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002006 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002007 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002008
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002009 for (j = 0; j < 10000; j++) {
2010 if (mode == MBEDTLS_AES_ENCRYPT) {
2011 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002012
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002013 memcpy(tmp, prv, 16);
2014 memcpy(prv, buf, 16);
2015 memcpy(buf, tmp, 16);
2016 }
2017
2018 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2019 if (ret != 0) {
2020 goto exit;
2021 }
2022
2023 }
2024
2025 if (memcmp(buf, aes_tests, 16) != 0) {
2026 ret = 1;
2027 goto exit;
2028 }
2029
2030 if (verbose != 0) {
2031 mbedtls_printf("passed\n");
2032 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002033 }
2034
Gilles Peskine449bd832023-01-11 14:50:10 +01002035 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002036 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002037 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002040
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002041#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002042 /*
2043 * CFB128 mode
2044 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002045 {
2046 static const int num_tests =
2047 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002048
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002049 for (i = 0; i < num_tests << 1; i++) {
2050 u = i >> 1;
2051 keybits = 128 + u * 64;
2052 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002053
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002054 if (verbose != 0) {
2055 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2056 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2057 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002058
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002059 memcpy(iv, aes_test_cfb128_iv, 16);
2060 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002061
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002062 offset = 0;
2063 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2064 /*
2065 * AES-192 is an optional feature that may be unavailable when
2066 * there is an alternative underlying implementation i.e. when
2067 * MBEDTLS_AES_ALT is defined.
2068 */
2069 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2070 mbedtls_printf("skipped\n");
2071 continue;
2072 } else if (ret != 0) {
2073 goto exit;
2074 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002075
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002076 if (mode == MBEDTLS_AES_DECRYPT) {
2077 memcpy(buf, aes_test_cfb128_ct[u], 64);
2078 aes_tests = aes_test_cfb128_pt;
2079 } else {
2080 memcpy(buf, aes_test_cfb128_pt, 64);
2081 aes_tests = aes_test_cfb128_ct[u];
2082 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002083
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002084 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2085 if (ret != 0) {
2086 goto exit;
2087 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002089 if (memcmp(buf, aes_tests, 64) != 0) {
2090 ret = 1;
2091 goto exit;
2092 }
2093
2094 if (verbose != 0) {
2095 mbedtls_printf("passed\n");
2096 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002097 }
2098
Gilles Peskine449bd832023-01-11 14:50:10 +01002099 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002100 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002101 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002102 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002103#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002104
Simon Butcherad4e4932018-04-29 00:43:47 +01002105#if defined(MBEDTLS_CIPHER_MODE_OFB)
2106 /*
2107 * OFB mode
2108 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002109 {
2110 static const int num_tests =
2111 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002112
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002113 for (i = 0; i < num_tests << 1; i++) {
2114 u = i >> 1;
2115 keybits = 128 + u * 64;
2116 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002117
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002118 if (verbose != 0) {
2119 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2120 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2121 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002122
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002123 memcpy(iv, aes_test_ofb_iv, 16);
2124 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002125
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002126 offset = 0;
2127 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2128 /*
2129 * AES-192 is an optional feature that may be unavailable when
2130 * there is an alternative underlying implementation i.e. when
2131 * MBEDTLS_AES_ALT is defined.
2132 */
2133 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2134 mbedtls_printf("skipped\n");
2135 continue;
2136 } else if (ret != 0) {
2137 goto exit;
2138 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002139
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002140 if (mode == MBEDTLS_AES_DECRYPT) {
2141 memcpy(buf, aes_test_ofb_ct[u], 64);
2142 aes_tests = aes_test_ofb_pt;
2143 } else {
2144 memcpy(buf, aes_test_ofb_pt, 64);
2145 aes_tests = aes_test_ofb_ct[u];
2146 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002147
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002148 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2149 if (ret != 0) {
2150 goto exit;
2151 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002152
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002153 if (memcmp(buf, aes_tests, 64) != 0) {
2154 ret = 1;
2155 goto exit;
2156 }
2157
2158 if (verbose != 0) {
2159 mbedtls_printf("passed\n");
2160 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002161 }
2162
Gilles Peskine449bd832023-01-11 14:50:10 +01002163 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002164 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002165 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002166 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002167#endif /* MBEDTLS_CIPHER_MODE_OFB */
2168
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002169#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002170 /*
2171 * CTR mode
2172 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002173 {
2174 static const int num_tests =
2175 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002176
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002177 for (i = 0; i < num_tests << 1; i++) {
2178 u = i >> 1;
2179 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002180
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002181 if (verbose != 0) {
2182 mbedtls_printf(" AES-CTR-128 (%s): ",
2183 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2184 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002185
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002186 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2187 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002188
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002189 offset = 0;
2190 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2191 goto exit;
2192 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002193
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002194 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 if (mode == MBEDTLS_AES_DECRYPT) {
2197 memcpy(buf, aes_test_ctr_ct[u], len);
2198 aes_tests = aes_test_ctr_pt[u];
2199 } else {
2200 memcpy(buf, aes_test_ctr_pt[u], len);
2201 aes_tests = aes_test_ctr_ct[u];
2202 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002203
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002204 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2205 stream_block, buf, buf);
2206 if (ret != 0) {
2207 goto exit;
2208 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002209
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002210 if (memcmp(buf, aes_tests, len) != 0) {
2211 ret = 1;
2212 goto exit;
2213 }
2214
2215 if (verbose != 0) {
2216 mbedtls_printf("passed\n");
2217 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002218 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002219 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002220
Gilles Peskine449bd832023-01-11 14:50:10 +01002221 if (verbose != 0) {
2222 mbedtls_printf("\n");
2223 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002224#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002225
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002226#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002227 /*
2228 * XTS mode
2229 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002230 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002231 static const int num_tests =
2232 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2233 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002234
Gilles Peskine449bd832023-01-11 14:50:10 +01002235 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002236
Gilles Peskine449bd832023-01-11 14:50:10 +01002237 for (i = 0; i < num_tests << 1; i++) {
2238 const unsigned char *data_unit;
2239 u = i >> 1;
2240 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002241
Gilles Peskine449bd832023-01-11 14:50:10 +01002242 if (verbose != 0) {
2243 mbedtls_printf(" AES-XTS-128 (%s): ",
2244 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2245 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 memset(key, 0, sizeof(key));
2248 memcpy(key, aes_test_xts_key[u], 32);
2249 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002250
Gilles Peskine449bd832023-01-11 14:50:10 +01002251 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002252
Gilles Peskine449bd832023-01-11 14:50:10 +01002253 if (mode == MBEDTLS_AES_DECRYPT) {
2254 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2255 if (ret != 0) {
2256 goto exit;
2257 }
2258 memcpy(buf, aes_test_xts_ct32[u], len);
2259 aes_tests = aes_test_xts_pt32[u];
2260 } else {
2261 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2262 if (ret != 0) {
2263 goto exit;
2264 }
2265 memcpy(buf, aes_test_xts_pt32[u], len);
2266 aes_tests = aes_test_xts_ct32[u];
2267 }
2268
2269
2270 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2271 buf, buf);
2272 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002273 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002274 }
2275
2276 if (memcmp(buf, aes_tests, len) != 0) {
2277 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002278 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002279 }
2280
2281 if (verbose != 0) {
2282 mbedtls_printf("passed\n");
2283 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002284 }
2285
Gilles Peskine449bd832023-01-11 14:50:10 +01002286 if (verbose != 0) {
2287 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002288 }
2289
Gilles Peskine449bd832023-01-11 14:50:10 +01002290 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002291 }
2292#endif /* MBEDTLS_CIPHER_MODE_XTS */
2293
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002294 ret = 0;
2295
2296exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002297 if (ret != 0 && verbose != 0) {
2298 mbedtls_printf("failed\n");
2299 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002300
Gilles Peskine449bd832023-01-11 14:50:10 +01002301 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002302
Gilles Peskine449bd832023-01-11 14:50:10 +01002303 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002304}
2305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002306#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002307
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002308#endif /* MBEDTLS_AES_C */