blob: 7c5c80621c2e49a6fac00ff4592f20127c551587 [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
Jerry Yu5fcdd6a2023-08-07 15:32:58 +080037#if defined(MBEDTLS_HAVE_ASM) && defined(__aarch64__)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yufce351d2023-08-04 17:13:36 +080043#if defined(MBEDTLS_HAVE_ASM) && \
Jerry Yu5fcdd6a2023-08-07 15:32:58 +080044 (defined(__amd64__) || defined(__x86_64__))
Jerry Yu02b15192023-04-23 14:43:19 +080045#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080046#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080047#endif
48#endif
49
Jerry Yufce351d2023-08-04 17:13:36 +080050#if defined(MBEDTLS_HAVE_ASM) && defined(__i386__) && \
Jerry Yu02b15192023-04-23 14:43:19 +080051 !defined(MBEDTLS_HAVE_ASAN)
Jerry Yu02b15192023-04-23 14:43:19 +080052#if !defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080053#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080054#endif
55#endif
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000058#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000059#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000061#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010062#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080063#if defined(MBEDTLS_AESCE_C)
64#include "aesce.h"
65#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000066
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020070
Gilles Peskine0f454e42023-03-16 14:58:46 +010071#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000072static int aes_padlock_ace = -1;
73#endif
74
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000076/*
77 * Forward S-box
78 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010079#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
80 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000081static const unsigned char FSb[256] =
82{
83 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
84 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
85 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
86 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
87 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
88 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
89 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
90 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
91 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
92 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
93 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
94 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
95 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
96 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
97 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
98 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
99 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
100 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
101 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
102 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
103 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
104 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
105 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
106 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
107 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
108 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
109 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
110 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
111 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
112 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
113 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
114 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
115};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100116#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
117 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000118
119/*
120 * Forward tables
121 */
122#define FT \
123\
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
125 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
126 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
127 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
128 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
129 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
130 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
131 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
132 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
133 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
134 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
135 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
136 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
137 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
138 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
139 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
140 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
141 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
142 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
143 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
144 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
145 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
146 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
147 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
148 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
149 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
150 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
151 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
152 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
153 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
154 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
155 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
156 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
157 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
158 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
159 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
160 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
161 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
162 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
163 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
164 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
165 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
166 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
167 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
168 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
169 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
170 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
171 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
172 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
173 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
174 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
175 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
176 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
177 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
178 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
179 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
180 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
181 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
182 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
183 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
184 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
185 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
186 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
187 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 +0000188
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100189#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100190#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000191static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000192#undef V
193
Hanno Beckerad049a92017-06-19 16:31:54 +0100194#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000197static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000198#undef V
199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000201static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000202#undef V
203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000205static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000206#undef V
207
Hanno Becker177d3cf2017-06-07 15:52:48 +0100208#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200209
Dave Rodgman1be24632023-06-29 12:01:24 +0100210#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
211
Paul Bakker5121ce52009-01-03 21:22:43 +0000212#undef FT
213
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100214#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000215/*
216 * Reverse S-box
217 */
218static const unsigned char RSb[256] =
219{
220 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
221 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
222 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
223 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
224 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
225 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
226 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
227 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
228 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
229 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
230 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
231 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
232 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
233 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
234 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
235 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
236 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
237 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
238 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
239 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
240 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
241 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
242 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
243 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
244 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
245 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
246 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
247 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
248 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
249 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
250 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
251 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
252};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100253#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255/*
256 * Reverse tables
257 */
258#define RT \
259\
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
261 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
262 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
263 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
264 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
265 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
266 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
267 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
268 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
269 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
270 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
271 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
272 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
273 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
274 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
275 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
276 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
277 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
278 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
279 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
280 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
281 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
282 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
283 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
284 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
285 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
286 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
287 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
288 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
289 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
290 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
291 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
292 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
293 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
294 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
295 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
296 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
297 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
298 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
299 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
300 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
301 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
302 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
303 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
304 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
305 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
306 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
307 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
308 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
309 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
310 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
311 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
312 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
313 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
314 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
315 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
316 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
317 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
318 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
319 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
320 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
321 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
322 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
323 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 +0000324
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100325#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000328static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000329#undef V
330
Hanno Beckerad049a92017-06-19 16:31:54 +0100331#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000335#undef V
336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000338static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000339#undef V
340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000342static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000343#undef V
344
Hanno Becker177d3cf2017-06-07 15:52:48 +0100345#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200346
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800347#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
348
Paul Bakker5121ce52009-01-03 21:22:43 +0000349#undef RT
350
Dave Rodgman34152a42023-06-27 18:31:24 +0100351#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000352/*
353 * Round constants
354 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000356{
357 0x00000001, 0x00000002, 0x00000004, 0x00000008,
358 0x00000010, 0x00000020, 0x00000040, 0x00000080,
359 0x0000001B, 0x00000036
360};
Dave Rodgman34152a42023-06-27 18:31:24 +0100361#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
365/*
366 * Forward S-box & tables
367 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100368#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
369 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000370static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100371#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
372 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100373#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200374static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100375#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200376static uint32_t FT1[256];
377static uint32_t FT2[256];
378static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100379#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100380#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
382/*
383 * Reverse S-box & tables
384 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100385#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000386static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100387#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100388
389#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000390static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100391#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000392static uint32_t RT1[256];
393static uint32_t RT2[256];
394static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100395#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100396#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Dave Rodgman8c753f92023-06-27 18:16:13 +0100398#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000399/*
400 * Round constants
401 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000402static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
404/*
405 * Tables generation code
406 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100407#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
408#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
409#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
411static int aes_init_done = 0;
412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000414{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800415 int i;
416 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800417 uint8_t pow[256];
418 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420 /*
421 * compute pow and log tables over GF(2^8)
422 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800425 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800426 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 }
428
429 /*
430 * calculate the round constants
431 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800433 RCON[i] = x;
434 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000435 }
436
437 /*
438 * generate the forward and reverse S-boxes
439 */
440 FSb[0x00] = 0x63;
441 RSb[0x63] = 0x00;
442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 x = pow[255 - log[i]];
445
Yanray Wangfe944ce2023-06-26 18:16:01 +0800446 y = x; y = (y << 1) | (y >> 7);
447 x ^= y; y = (y << 1) | (y >> 7);
448 x ^= y; y = (y << 1) | (y >> 7);
449 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 x ^= y ^ 0x63;
451
Yanray Wangfe944ce2023-06-26 18:16:01 +0800452 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 RSb[x] = (unsigned char) i;
454 }
455
456 /*
457 * generate the forward and reverse tables
458 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000460 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800461 y = XTIME(x);
462 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 FT0[i] = ((uint32_t) y) ^
465 ((uint32_t) x << 8) ^
466 ((uint32_t) x << 16) ^
467 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
Hanno Beckerad049a92017-06-19 16:31:54 +0100469#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 FT1[i] = ROTL8(FT0[i]);
471 FT2[i] = ROTL8(FT1[i]);
472 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100473#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
475 x = RSb[i];
476
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100477#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
479 ((uint32_t) MUL(0x09, x) << 8) ^
480 ((uint32_t) MUL(0x0D, x) << 16) ^
481 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Hanno Beckerad049a92017-06-19 16:31:54 +0100483#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 RT1[i] = ROTL8(RT0[i]);
485 RT2[i] = ROTL8(RT1[i]);
486 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100487#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100488#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000489 }
490}
491
Dave Rodgman8c753f92023-06-27 18:16:13 +0100492#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
493
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200494#undef ROTL8
495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000497
Hanno Beckerad049a92017-06-19 16:31:54 +0100498#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
501#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
502#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200503
504#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100505#define AES_RT1(idx) ROTL8(RT0[idx])
506#define AES_RT2(idx) ROTL16(RT0[idx])
507#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200508
509#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100510#define AES_FT1(idx) ROTL8(FT0[idx])
511#define AES_FT2(idx) ROTL16(FT0[idx])
512#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200513
Hanno Becker177d3cf2017-06-07 15:52:48 +0100514#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200515
516#define AES_RT0(idx) RT0[idx]
517#define AES_RT1(idx) RT1[idx]
518#define AES_RT2(idx) RT2[idx]
519#define AES_RT3(idx) RT3[idx]
520
521#define AES_FT0(idx) FT0[idx]
522#define AES_FT1(idx) FT1[idx]
523#define AES_FT2(idx) FT2[idx]
524#define AES_FT3(idx) FT3[idx]
525
Hanno Becker177d3cf2017-06-07 15:52:48 +0100526#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200529{
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200531}
532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200534{
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200536 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200540}
541
Jaeden Amero9366feb2018-05-29 18:55:17 +0100542#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100543void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100544{
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 mbedtls_aes_init(&ctx->crypt);
546 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100547}
548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100550{
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100552 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 }
Simon Butcher5201e412018-12-06 17:40:14 +0000554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 mbedtls_aes_free(&ctx->crypt);
556 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100557}
558#endif /* MBEDTLS_CIPHER_MODE_XTS */
559
Gilles Peskine0de8f852023-03-16 17:14:59 +0100560/* Some implementations need the round keys to be aligned.
561 * Return an offset to be added to buf, such that (buf + offset) is
562 * correctly aligned.
563 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
564 * i.e. an offset of 1 means 4 bytes and so on.
565 */
566#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100567 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100568#define MAY_NEED_TO_ALIGN
569#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100570
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100571#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
572 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100573static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
574{
575#if defined(MAY_NEED_TO_ALIGN)
576 int align_16_bytes = 0;
577
578#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
579 if (aes_padlock_ace == -1) {
580 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
581 }
582 if (aes_padlock_ace) {
583 align_16_bytes = 1;
584 }
585#endif
586
Gilles Peskine9c682e72023-03-16 17:21:33 +0100587#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100588 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
589 align_16_bytes = 1;
590 }
591#endif
592
593 if (align_16_bytes) {
594 /* These implementations needs 16-byte alignment
595 * for the round key array. */
596 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
597 if (delta == 0) {
598 return 0;
599 } else {
600 return 4 - delta; // 16 bytes = 4 uint32_t
601 }
602 }
603#else /* MAY_NEED_TO_ALIGN */
604 (void) buf;
605#endif /* MAY_NEED_TO_ALIGN */
606
607 return 0;
608}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100609#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
610 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100611
Paul Bakker5121ce52009-01-03 21:22:43 +0000612/*
613 * AES key schedule (encryption)
614 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200615#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100616int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
617 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000618{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800619#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Paul Bakker23986e52011-04-24 08:57:21 +0000620 unsigned int i;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800621#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000622 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800626#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 case 192: ctx->nr = 12; break;
628 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800629#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 }
632
Simon Butcher5201e412018-12-06 17:40:14 +0000633#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000635 aes_gen_tables();
636 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000637 }
638#endif
639
Gilles Peskine0de8f852023-03-16 17:14:59 +0100640 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100641 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000642
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100643#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
645 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
646 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100647#endif
648
Jerry Yu3f2fb712023-01-10 17:05:42 +0800649#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
650 if (mbedtls_aesce_has_support()) {
651 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
652 }
653#endif
654
Jerry Yu29c91ba2023-08-04 11:02:04 +0800655#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 for (i = 0; i < (keybits >> 5); i++) {
657 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000658 }
659
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 case 10:
662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
666 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
667 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
668 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000669
670 RK[5] = RK[1] ^ RK[4];
671 RK[6] = RK[2] ^ RK[5];
672 RK[7] = RK[3] ^ RK[6];
673 }
674 break;
675
Arto Kinnunen732ca322023-04-14 14:26:10 +0800676#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000677 case 12:
678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000680 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
682 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
683 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
684 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000685
686 RK[7] = RK[1] ^ RK[6];
687 RK[8] = RK[2] ^ RK[7];
688 RK[9] = RK[3] ^ RK[8];
689 RK[10] = RK[4] ^ RK[9];
690 RK[11] = RK[5] ^ RK[10];
691 }
692 break;
693
694 case 14:
695
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000697 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
699 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
700 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
701 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000702
703 RK[9] = RK[1] ^ RK[8];
704 RK[10] = RK[2] ^ RK[9];
705 RK[11] = RK[3] ^ RK[10];
706
707 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
709 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
710 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
711 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
713 RK[13] = RK[5] ^ RK[12];
714 RK[14] = RK[6] ^ RK[13];
715 RK[15] = RK[7] ^ RK[14];
716 }
717 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800718#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000719 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000720
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800722#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000723}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200724#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000725
726/*
727 * AES key schedule (decryption)
728 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200729#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100730int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
731 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000732{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800733#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
734 int i, j;
735 uint32_t *SK;
736#endif
737 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000739 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800740
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000743
Gilles Peskine0de8f852023-03-16 17:14:59 +0100744 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100745 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000746
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200747 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200749 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000751
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200752 ctx->nr = cty.nr;
753
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100754#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
756 mbedtls_aesni_inverse_key((unsigned char *) RK,
757 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200758 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100759 }
760#endif
761
Jerry Yue096da12023-01-10 17:07:01 +0800762#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
763 if (mbedtls_aesce_has_support()) {
764 mbedtls_aesce_inverse_key(
765 (unsigned char *) RK,
766 (const unsigned char *) (cty.buf + cty.rk_offset),
767 ctx->nr);
768 goto exit;
769 }
770#endif
771
Jerry Yu29c91ba2023-08-04 11:02:04 +0800772#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100773 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000774
775 *RK++ = *SK++;
776 *RK++ = *SK++;
777 *RK++ = *SK++;
778 *RK++ = *SK++;
779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
781 for (j = 0; j < 4; j++, SK++) {
782 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
783 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
784 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
785 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 }
787 }
788
789 *RK++ = *SK++;
790 *RK++ = *SK++;
791 *RK++ = *SK++;
792 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800793#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200794exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000798}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100799#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100800
801#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100802static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
803 unsigned int keybits,
804 const unsigned char **key1,
805 unsigned int *key1bits,
806 const unsigned char **key2,
807 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808{
809 const unsigned int half_keybits = keybits / 2;
810 const unsigned int half_keybytes = half_keybits / 8;
811
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100813 case 256: break;
814 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100816 }
817
818 *key1bits = half_keybits;
819 *key2bits = half_keybits;
820 *key1 = &key[0];
821 *key2 = &key[half_keybytes];
822
823 return 0;
824}
825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
827 const unsigned char *key,
828 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100829{
Janos Follath24eed8d2019-11-22 13:21:35 +0000830 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100831 const unsigned char *key1, *key2;
832 unsigned int key1bits, key2bits;
833
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
835 &key2, &key2bits);
836 if (ret != 0) {
837 return ret;
838 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100839
840 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
842 if (ret != 0) {
843 return ret;
844 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100845
846 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100848}
849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
851 const unsigned char *key,
852 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100853{
Janos Follath24eed8d2019-11-22 13:21:35 +0000854 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100855 const unsigned char *key1, *key2;
856 unsigned int key1bits, key2bits;
857
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
859 &key2, &key2bits);
860 if (ret != 0) {
861 return ret;
862 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100863
864 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
866 if (ret != 0) {
867 return ret;
868 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100869
870 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100872}
873#endif /* MBEDTLS_CIPHER_MODE_XTS */
874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100876 do \
877 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
879 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
880 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
881 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100882 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
884 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
885 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
886 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100887 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
889 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
890 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
891 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100892 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
894 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
895 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
896 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
897 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100900 do \
901 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
903 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
904 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
905 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100906 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
908 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
909 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
910 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100911 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
913 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
914 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
915 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100916 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
918 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
919 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
920 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
921 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000922
923/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200924 * AES-ECB block encryption
925 */
926#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100927int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
928 const unsigned char input[16],
929 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930{
931 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100932 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200934 uint32_t X[4];
935 uint32_t Y[4];
936 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200937
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
939 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
940 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
941 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
944 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]);
945 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 +0200946 }
947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 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 +0200949
Gilles Peskine5197c662020-08-26 17:03:24 +0200950 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
952 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
953 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
954 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955
Gilles Peskine5197c662020-08-26 17:03:24 +0200956 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
958 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
959 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
960 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200961
Gilles Peskine5197c662020-08-26 17:03:24 +0200962 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
965 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
966 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Gilles Peskine5197c662020-08-26 17:03:24 +0200968 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
971 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
972 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
975 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
976 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
977 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500980
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200982}
983#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
984
985/*
986 * AES-ECB block decryption
987 */
988#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100989int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
990 const unsigned char input[16],
991 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992{
993 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100994 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200996 uint32_t X[4];
997 uint32_t Y[4];
998 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1001 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1002 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1003 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1006 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]);
1007 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 +02001008 }
1009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 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 +02001011
Gilles Peskine5197c662020-08-26 17:03:24 +02001012 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1014 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1015 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1016 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001017
Gilles Peskine5197c662020-08-26 17:03:24 +02001018 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1020 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1021 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1022 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001023
Gilles Peskine5197c662020-08-26 17:03:24 +02001024 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1027 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1028 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001029
Gilles Peskine5197c662020-08-26 17:03:24 +02001030 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1033 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1034 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001035
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1037 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1038 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1039 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001044}
1045#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1046
Gilles Peskine0de8f852023-03-16 17:14:59 +01001047#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001048/* VIA Padlock and our intrinsics-based implementation of AESNI require
1049 * the round keys to be aligned on a 16-byte boundary. We take care of this
1050 * before creating them, but the AES context may have moved (this can happen
1051 * if the library is called from a language with managed memory), and in later
1052 * calls it might have a different alignment with respect to 16-byte memory.
1053 * So we may need to realign.
1054 */
1055static void aes_maybe_realign(mbedtls_aes_context *ctx)
1056{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001057 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1058 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001059 memmove(ctx->buf + new_offset, // new address
1060 ctx->buf + ctx->rk_offset, // current address
1061 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1062 ctx->rk_offset = new_offset;
1063 }
1064}
1065#endif
1066
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001067/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001068 * AES-ECB block encryption/decryption
1069 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001070int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1071 int mode,
1072 const unsigned char input[16],
1073 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001074{
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001076 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001078
Gilles Peskine0de8f852023-03-16 17:14:59 +01001079#if defined(MAY_NEED_TO_ALIGN)
1080 aes_maybe_realign(ctx);
1081#endif
1082
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001083#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1085 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1086 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001087#endif
1088
Jerry Yu2bb3d812023-01-10 17:38:26 +08001089#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1090 if (mbedtls_aesce_has_support()) {
1091 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1092 }
1093#endif
1094
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001095#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001097 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001098 }
1099#endif
1100
Jerry Yu29c91ba2023-08-04 11:02:04 +08001101#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 if (mode == MBEDTLS_AES_ENCRYPT) {
1103 return mbedtls_internal_aes_encrypt(ctx, input, output);
1104 } else {
1105 return mbedtls_internal_aes_decrypt(ctx, input, output);
1106 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001107#endif
1108
Paul Bakker5121ce52009-01-03 21:22:43 +00001109}
1110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001111#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001112
Paul Bakker5121ce52009-01-03 21:22:43 +00001113/*
1114 * AES-CBC buffer encryption/decryption
1115 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001116int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1117 int mode,
1118 size_t length,
1119 unsigned char iv[16],
1120 const unsigned char *input,
1121 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001122{
Gilles Peskine7820a572021-07-07 21:08:28 +02001123 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001124 unsigned char temp[16];
1125
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001127 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 if (length % 16) {
1131 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1132 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001133
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001134#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 if (aes_padlock_ace > 0) {
1136 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1137 return 0;
1138 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001139
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001140 // If padlock data misaligned, we just fall back to
1141 // unaccelerated mode
1142 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001143 }
1144#endif
1145
Dave Rodgman906c63c2023-06-14 17:53:51 +01001146 const unsigned char *ivp = iv;
1147
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 if (mode == MBEDTLS_AES_DECRYPT) {
1149 while (length > 0) {
1150 memcpy(temp, input, 16);
1151 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1152 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001153 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001155 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001156 * the result for the next block in CBC, and the cost of transferring that data from
1157 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001158 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001159
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001161
1162 input += 16;
1163 output += 16;
1164 length -= 16;
1165 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 } else {
1167 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001168 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001169
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1171 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001172 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001174 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001175
1176 input += 16;
1177 output += 16;
1178 length -= 16;
1179 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001180 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001181 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001182 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001183
Gilles Peskine7820a572021-07-07 21:08:28 +02001184exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001186}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001187#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001188
Aorimn5f778012016-06-09 23:22:58 +02001189#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001190
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001191typedef unsigned char mbedtls_be128[16];
1192
1193/*
1194 * GF(2^128) multiplication function
1195 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001196 * This function multiplies a field element by x in the polynomial field
1197 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001198 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001199 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001200 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001201#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001202MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001203#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001204static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001205 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001206{
1207 uint64_t a, b, ra, rb;
1208
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 a = MBEDTLS_GET_UINT64_LE(x, 0);
1210 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1213 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001214
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1216 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001217}
1218
Aorimn5f778012016-06-09 23:22:58 +02001219/*
1220 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001221 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001222 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001223 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001224 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001225#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001226MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001227#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001228int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1229 int mode,
1230 size_t length,
1231 const unsigned char data_unit[16],
1232 const unsigned char *input,
1233 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001234{
Janos Follath24eed8d2019-11-22 13:21:35 +00001235 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001236 size_t blocks = length / 16;
1237 size_t leftover = length % 16;
1238 unsigned char tweak[16];
1239 unsigned char prev_tweak[16];
1240 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001241
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001243 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001245
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001246 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001248 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 }
Aorimn5f778012016-06-09 23:22:58 +02001250
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001251 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001253 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 }
Aorimn5f778012016-06-09 23:22:58 +02001255
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1258 data_unit, tweak);
1259 if (ret != 0) {
1260 return ret;
1261 }
Aorimn5f778012016-06-09 23:22:58 +02001262
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001264 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 /* We are on the last block in a decrypt operation that has
1266 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001267 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001268 * the leftovers and then update the current tweak for use on this,
1269 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001270 memcpy(prev_tweak, tweak, sizeof(tweak));
1271 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001272 }
1273
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275
Gilles Peskine449bd832023-01-11 14:50:10 +01001276 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1277 if (ret != 0) {
1278 return ret;
1279 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001280
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282
1283 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285
1286 output += 16;
1287 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001288 }
1289
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001291 /* If we are on the leftover bytes in a decrypt operation, we need to
1292 * use the previous tweak for these bytes (as saved in prev_tweak). */
1293 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001294
Jaeden Amerod82cd862018-04-28 15:02:45 +01001295 /* We are now on the final part of the data unit, which doesn't divide
1296 * evenly by 16. It's time for ciphertext stealing. */
1297 size_t i;
1298 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001299
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001301 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001302 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001303 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001304 }
Aorimn5f778012016-06-09 23:22:58 +02001305
Dave Rodgman069e7f42022-11-24 19:37:26 +00001306 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001308
Jaeden Amerod82cd862018-04-28 15:02:45 +01001309 /* Copy ciphertext bytes from the previous block for input in this
1310 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001312
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1314 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001315 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 }
Aorimn5f778012016-06-09 23:22:58 +02001317
Jaeden Amerod82cd862018-04-28 15:02:45 +01001318 /* Write the result back to the previous block, overriding the previous
1319 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001321 }
1322
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001324}
1325#endif /* MBEDTLS_CIPHER_MODE_XTS */
1326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001327#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001328/*
1329 * AES-CFB128 buffer encryption/decryption
1330 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001331int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1332 int mode,
1333 size_t length,
1334 size_t *iv_off,
1335 unsigned char iv[16],
1336 const unsigned char *input,
1337 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001338{
Paul Bakker27fdf462011-06-09 13:55:13 +00001339 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001340 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001341 size_t n;
1342
Gilles Peskine449bd832023-01-11 14:50:10 +01001343 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001344 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001346
1347 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 if (n > 15) {
1350 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1351 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001352
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 if (mode == MBEDTLS_AES_DECRYPT) {
1354 while (length--) {
1355 if (n == 0) {
1356 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1357 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001358 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001360 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001361
1362 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001364 iv[n] = (unsigned char) c;
1365
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 } else {
1369 while (length--) {
1370 if (n == 0) {
1371 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1372 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001373 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001375 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001376
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001378
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001380 }
1381 }
1382
1383 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001384 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001385
Gilles Peskine7820a572021-07-07 21:08:28 +02001386exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001388}
Paul Bakker556efba2014-01-24 15:38:12 +01001389
1390/*
1391 * AES-CFB8 buffer encryption/decryption
1392 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001393int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1394 int mode,
1395 size_t length,
1396 unsigned char iv[16],
1397 const unsigned char *input,
1398 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001399{
Gilles Peskine7820a572021-07-07 21:08:28 +02001400 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001401 unsigned char c;
1402 unsigned char ov[17];
1403
Gilles Peskine449bd832023-01-11 14:50:10 +01001404 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001405 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001406 }
1407 while (length--) {
1408 memcpy(ov, iv, 16);
1409 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1410 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001411 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001412 }
Paul Bakker556efba2014-01-24 15:38:12 +01001413
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001415 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 }
Paul Bakker556efba2014-01-24 15:38:12 +01001417
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001419
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001421 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 }
Paul Bakker556efba2014-01-24 15:38:12 +01001423
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001425 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001426 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001427
Gilles Peskine7820a572021-07-07 21:08:28 +02001428exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001430}
Simon Butcher76a5b222018-04-22 22:57:27 +01001431#endif /* MBEDTLS_CIPHER_MODE_CFB */
1432
1433#if defined(MBEDTLS_CIPHER_MODE_OFB)
1434/*
1435 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1436 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001437int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1438 size_t length,
1439 size_t *iv_off,
1440 unsigned char iv[16],
1441 const unsigned char *input,
1442 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001443{
Simon Butcherad4e4932018-04-29 00:43:47 +01001444 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001445 size_t n;
1446
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001447 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001448
Gilles Peskine449bd832023-01-11 14:50:10 +01001449 if (n > 15) {
1450 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1451 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001452
Gilles Peskine449bd832023-01-11 14:50:10 +01001453 while (length--) {
1454 if (n == 0) {
1455 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1456 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001457 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001458 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001459 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001460 *output++ = *input++ ^ iv[n];
1461
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001463 }
1464
1465 *iv_off = n;
1466
Simon Butcherad4e4932018-04-29 00:43:47 +01001467exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001468 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001469}
1470#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001473/*
1474 * AES-CTR buffer encryption/decryption
1475 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001476int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1477 size_t length,
1478 size_t *nc_off,
1479 unsigned char nonce_counter[16],
1480 unsigned char stream_block[16],
1481 const unsigned char *input,
1482 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483{
Paul Bakker369e14b2012-04-18 14:16:09 +00001484 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001485 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001486 size_t n;
1487
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001488 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489
Gilles Peskine449bd832023-01-11 14:50:10 +01001490 if (n > 0x0F) {
1491 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1492 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001493
Gilles Peskine449bd832023-01-11 14:50:10 +01001494 while (length--) {
1495 if (n == 0) {
1496 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1497 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001498 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001499 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001500
Gilles Peskine449bd832023-01-11 14:50:10 +01001501 for (i = 16; i > 0; i--) {
1502 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001503 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001504 }
1505 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001506 }
1507 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001508 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001509
Gilles Peskine449bd832023-01-11 14:50:10 +01001510 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001511 }
1512
1513 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001514 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001515
Gilles Peskine7820a572021-07-07 21:08:28 +02001516exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001517 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001518}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001521#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001524/*
1525 * AES test vectors from:
1526 *
1527 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1528 */
Yanray Wang62c99912023-05-11 11:06:53 +08001529static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001530{
1531 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1532 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001533#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001534 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1535 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1536 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1537 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001538#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001539};
1540
Yanray Wang62c99912023-05-11 11:06:53 +08001541static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001542{
1543 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1544 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001545#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001546 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1547 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1548 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1549 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001550#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001551};
1552
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001553#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001554static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001555{
1556 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1557 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001558#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001559 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1560 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1561 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1562 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001563#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001564};
1565
Yanray Wang62c99912023-05-11 11:06:53 +08001566static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001567{
1568 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1569 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001570#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001571 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1572 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1573 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1574 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001575#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001576};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001577#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001579#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001580/*
1581 * AES-CFB128 test vectors from:
1582 *
1583 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1584 */
Yanray Wang62c99912023-05-11 11:06:53 +08001585static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001586{
1587 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1588 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001589#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001590 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1591 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1592 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1593 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1594 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1595 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1596 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001597#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001598};
1599
1600static const unsigned char aes_test_cfb128_iv[16] =
1601{
1602 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1603 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1604};
1605
1606static const unsigned char aes_test_cfb128_pt[64] =
1607{
1608 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1609 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1610 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1611 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1612 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1613 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1614 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1615 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1616};
1617
Yanray Wang62c99912023-05-11 11:06:53 +08001618static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001619{
1620 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1621 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1622 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1623 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1624 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1625 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1626 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1627 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001628#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001629 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1630 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1631 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1632 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1633 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1634 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1635 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1636 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1637 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1638 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1639 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1640 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1641 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1642 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1643 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1644 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001645#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001646};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001647#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001648
Simon Butcherad4e4932018-04-29 00:43:47 +01001649#if defined(MBEDTLS_CIPHER_MODE_OFB)
1650/*
1651 * AES-OFB test vectors from:
1652 *
Simon Butcher5db13622018-06-04 22:11:25 +01001653 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001654 */
Yanray Wang62c99912023-05-11 11:06:53 +08001655static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001656{
1657 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1658 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001659#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001660 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1661 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1662 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1663 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1664 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1665 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1666 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001667#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001668};
1669
1670static const unsigned char aes_test_ofb_iv[16] =
1671{
1672 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1673 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1674};
1675
1676static const unsigned char aes_test_ofb_pt[64] =
1677{
1678 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1679 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1680 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1681 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1682 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1683 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1684 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1685 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1686};
1687
Yanray Wang62c99912023-05-11 11:06:53 +08001688static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001689{
1690 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1691 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1692 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1693 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1694 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1695 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1696 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1697 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001698#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001699 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1700 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1701 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1702 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1703 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1704 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1705 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1706 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1707 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1708 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1709 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1710 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1711 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1712 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1713 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1714 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001715#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001716};
1717#endif /* MBEDTLS_CIPHER_MODE_OFB */
1718
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001719#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001720/*
1721 * AES-CTR test vectors from:
1722 *
1723 * http://www.faqs.org/rfcs/rfc3686.html
1724 */
1725
Yanray Wang62c99912023-05-11 11:06:53 +08001726static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001727{
1728 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1729 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1730 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1731 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1732 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1733 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1734};
1735
Yanray Wang62c99912023-05-11 11:06:53 +08001736static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001737{
1738 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1740 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1741 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1742 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1743 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1744};
1745
Yanray Wang62c99912023-05-11 11:06:53 +08001746static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001747{
1748 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1749 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001750 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1751 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1752 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1753 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1754
1755 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1756 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1757 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1758 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1759 0x20, 0x21, 0x22, 0x23 }
1760};
1761
Yanray Wang62c99912023-05-11 11:06:53 +08001762static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001763{
1764 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1765 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1766 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1767 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1768 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1769 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1770 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1771 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1772 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1773 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1774 0x25, 0xB2, 0x07, 0x2F }
1775};
1776
1777static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001778{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001779#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001780
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001781#if defined(MBEDTLS_CIPHER_MODE_XTS)
1782/*
1783 * AES-XTS test vectors from:
1784 *
1785 * IEEE P1619/D16 Annex B
1786 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1787 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1788 */
1789static const unsigned char aes_test_xts_key[][32] =
1790{
1791 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1795 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1796 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1797 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1798 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1799 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1800 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1801 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1802 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1803};
1804
1805static const unsigned char aes_test_xts_pt32[][32] =
1806{
1807 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1811 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1812 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1813 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1814 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1815 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1816 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1817 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1818 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1819};
1820
1821static const unsigned char aes_test_xts_ct32[][32] =
1822{
1823 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1824 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1825 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1826 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1827 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1828 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1829 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1830 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1831 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1832 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1833 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1834 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1835};
1836
1837static const unsigned char aes_test_xts_data_unit[][16] =
1838{
Gilles Peskine449bd832023-01-11 14:50:10 +01001839 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1841 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1843 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001845};
1846
1847#endif /* MBEDTLS_CIPHER_MODE_XTS */
1848
Paul Bakker5121ce52009-01-03 21:22:43 +00001849/*
1850 * Checkup routine
1851 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001852int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001853{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001854 int ret = 0, i, j, u, mode;
1855 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001856 unsigned char key[32];
1857 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001858 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001859#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1860 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001861 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001862#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001863#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001864 unsigned char prv[16];
1865#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001866#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1867 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001868 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001869#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001870#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001871 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001872#endif
1873#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001874 unsigned char nonce_counter[16];
1875 unsigned char stream_block[16];
1876#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001877 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
Gilles Peskine449bd832023-01-11 14:50:10 +01001879 memset(key, 0, 32);
1880 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001881
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001882 if (verbose != 0) {
1883#if defined(MBEDTLS_AES_ALT)
1884 mbedtls_printf(" AES note: alternative implementation.\n");
1885#else /* MBEDTLS_AES_ALT */
1886#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1887 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1888 mbedtls_printf(" AES note: using VIA Padlock.\n");
1889 } else
1890#endif
1891#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001892#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001893 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001894#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001895 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001896#else
1897#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1898#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001899 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1900 mbedtls_printf(" AES note: using AESNI.\n");
1901 } else
1902#endif
1903#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1904 if (mbedtls_aesce_has_support()) {
1905 mbedtls_printf(" AES note: using AESCE.\n");
1906 } else
1907#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001908 {
1909#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1910 mbedtls_printf(" AES note: built-in implementation.\n");
1911#endif
1912 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001913#endif /* MBEDTLS_AES_ALT */
1914 }
1915
Paul Bakker5121ce52009-01-03 21:22:43 +00001916 /*
1917 * ECB mode
1918 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001919 {
1920 static const int num_tests =
1921 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001923 for (i = 0; i < num_tests << 1; i++) {
1924 u = i >> 1;
1925 keybits = 128 + u * 64;
1926 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001927
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001928 if (verbose != 0) {
1929 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1930 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1931 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001932
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001933 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001934
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001935 if (mode == MBEDTLS_AES_DECRYPT) {
1936 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1937 aes_tests = aes_test_ecb_dec[u];
1938 } else {
1939 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1940 aes_tests = aes_test_ecb_enc[u];
1941 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001942
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001943 /*
1944 * AES-192 is an optional feature that may be unavailable when
1945 * there is an alternative underlying implementation i.e. when
1946 * MBEDTLS_AES_ALT is defined.
1947 */
1948 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1949 mbedtls_printf("skipped\n");
1950 continue;
1951 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001952 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001953 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001954
1955 for (j = 0; j < 10000; j++) {
1956 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1957 if (ret != 0) {
1958 goto exit;
1959 }
1960 }
1961
1962 if (memcmp(buf, aes_tests, 16) != 0) {
1963 ret = 1;
1964 goto exit;
1965 }
1966
1967 if (verbose != 0) {
1968 mbedtls_printf("passed\n");
1969 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001970 }
1971
Gilles Peskine449bd832023-01-11 14:50:10 +01001972 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001973 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001974 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001975 }
1976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001977#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001978 /*
1979 * CBC mode
1980 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001981 {
1982 static const int num_tests =
1983 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001984
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001985 for (i = 0; i < num_tests << 1; i++) {
1986 u = i >> 1;
1987 keybits = 128 + u * 64;
1988 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001989
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001990 if (verbose != 0) {
1991 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1992 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 }
1994
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001995 memset(iv, 0, 16);
1996 memset(prv, 0, 16);
1997 memset(buf, 0, 16);
1998
1999 if (mode == MBEDTLS_AES_DECRYPT) {
2000 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2001 aes_tests = aes_test_cbc_dec[u];
2002 } else {
2003 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2004 aes_tests = aes_test_cbc_enc[u];
2005 }
2006
2007 /*
2008 * AES-192 is an optional feature that may be unavailable when
2009 * there is an alternative underlying implementation i.e. when
2010 * MBEDTLS_AES_ALT is defined.
2011 */
2012 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2013 mbedtls_printf("skipped\n");
2014 continue;
2015 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002016 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002017 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002018
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002019 for (j = 0; j < 10000; j++) {
2020 if (mode == MBEDTLS_AES_ENCRYPT) {
2021 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002022
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002023 memcpy(tmp, prv, 16);
2024 memcpy(prv, buf, 16);
2025 memcpy(buf, tmp, 16);
2026 }
2027
2028 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2029 if (ret != 0) {
2030 goto exit;
2031 }
2032
2033 }
2034
2035 if (memcmp(buf, aes_tests, 16) != 0) {
2036 ret = 1;
2037 goto exit;
2038 }
2039
2040 if (verbose != 0) {
2041 mbedtls_printf("passed\n");
2042 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 }
2044
Gilles Peskine449bd832023-01-11 14:50:10 +01002045 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002046 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002047 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002049#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002051#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 /*
2053 * CFB128 mode
2054 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002055 {
2056 static const int num_tests =
2057 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002058
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002059 for (i = 0; i < num_tests << 1; i++) {
2060 u = i >> 1;
2061 keybits = 128 + u * 64;
2062 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002063
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002064 if (verbose != 0) {
2065 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2066 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2067 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002068
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002069 memcpy(iv, aes_test_cfb128_iv, 16);
2070 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002071
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002072 offset = 0;
2073 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2074 /*
2075 * AES-192 is an optional feature that may be unavailable when
2076 * there is an alternative underlying implementation i.e. when
2077 * MBEDTLS_AES_ALT is defined.
2078 */
2079 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2080 mbedtls_printf("skipped\n");
2081 continue;
2082 } else if (ret != 0) {
2083 goto exit;
2084 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002085
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002086 if (mode == MBEDTLS_AES_DECRYPT) {
2087 memcpy(buf, aes_test_cfb128_ct[u], 64);
2088 aes_tests = aes_test_cfb128_pt;
2089 } else {
2090 memcpy(buf, aes_test_cfb128_pt, 64);
2091 aes_tests = aes_test_cfb128_ct[u];
2092 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002093
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002094 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2095 if (ret != 0) {
2096 goto exit;
2097 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002098
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002099 if (memcmp(buf, aes_tests, 64) != 0) {
2100 ret = 1;
2101 goto exit;
2102 }
2103
2104 if (verbose != 0) {
2105 mbedtls_printf("passed\n");
2106 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002107 }
2108
Gilles Peskine449bd832023-01-11 14:50:10 +01002109 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002110 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002111 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002112 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002113#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002114
Simon Butcherad4e4932018-04-29 00:43:47 +01002115#if defined(MBEDTLS_CIPHER_MODE_OFB)
2116 /*
2117 * OFB mode
2118 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002119 {
2120 static const int num_tests =
2121 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002122
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002123 for (i = 0; i < num_tests << 1; i++) {
2124 u = i >> 1;
2125 keybits = 128 + u * 64;
2126 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002127
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002128 if (verbose != 0) {
2129 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2130 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2131 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002132
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002133 memcpy(iv, aes_test_ofb_iv, 16);
2134 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002135
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002136 offset = 0;
2137 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2138 /*
2139 * AES-192 is an optional feature that may be unavailable when
2140 * there is an alternative underlying implementation i.e. when
2141 * MBEDTLS_AES_ALT is defined.
2142 */
2143 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2144 mbedtls_printf("skipped\n");
2145 continue;
2146 } else if (ret != 0) {
2147 goto exit;
2148 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002149
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002150 if (mode == MBEDTLS_AES_DECRYPT) {
2151 memcpy(buf, aes_test_ofb_ct[u], 64);
2152 aes_tests = aes_test_ofb_pt;
2153 } else {
2154 memcpy(buf, aes_test_ofb_pt, 64);
2155 aes_tests = aes_test_ofb_ct[u];
2156 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002157
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002158 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2159 if (ret != 0) {
2160 goto exit;
2161 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002162
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002163 if (memcmp(buf, aes_tests, 64) != 0) {
2164 ret = 1;
2165 goto exit;
2166 }
2167
2168 if (verbose != 0) {
2169 mbedtls_printf("passed\n");
2170 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002171 }
2172
Gilles Peskine449bd832023-01-11 14:50:10 +01002173 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002174 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002175 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002176 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002177#endif /* MBEDTLS_CIPHER_MODE_OFB */
2178
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002179#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002180 /*
2181 * CTR mode
2182 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002183 {
2184 static const int num_tests =
2185 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002186
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002187 for (i = 0; i < num_tests << 1; i++) {
2188 u = i >> 1;
2189 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002190
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002191 if (verbose != 0) {
2192 mbedtls_printf(" AES-CTR-128 (%s): ",
2193 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2194 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2197 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002198
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002199 offset = 0;
2200 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2201 goto exit;
2202 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002203
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002204 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002205
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002206 if (mode == MBEDTLS_AES_DECRYPT) {
2207 memcpy(buf, aes_test_ctr_ct[u], len);
2208 aes_tests = aes_test_ctr_pt[u];
2209 } else {
2210 memcpy(buf, aes_test_ctr_pt[u], len);
2211 aes_tests = aes_test_ctr_ct[u];
2212 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002213
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002214 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2215 stream_block, buf, buf);
2216 if (ret != 0) {
2217 goto exit;
2218 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002219
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002220 if (memcmp(buf, aes_tests, len) != 0) {
2221 ret = 1;
2222 goto exit;
2223 }
2224
2225 if (verbose != 0) {
2226 mbedtls_printf("passed\n");
2227 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002228 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002229 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002230
Gilles Peskine449bd832023-01-11 14:50:10 +01002231 if (verbose != 0) {
2232 mbedtls_printf("\n");
2233 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002234#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002235
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002236#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002237 /*
2238 * XTS mode
2239 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002240 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002241 static const int num_tests =
2242 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2243 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002244
Gilles Peskine449bd832023-01-11 14:50:10 +01002245 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 for (i = 0; i < num_tests << 1; i++) {
2248 const unsigned char *data_unit;
2249 u = i >> 1;
2250 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002251
Gilles Peskine449bd832023-01-11 14:50:10 +01002252 if (verbose != 0) {
2253 mbedtls_printf(" AES-XTS-128 (%s): ",
2254 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2255 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002256
Gilles Peskine449bd832023-01-11 14:50:10 +01002257 memset(key, 0, sizeof(key));
2258 memcpy(key, aes_test_xts_key[u], 32);
2259 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002260
Gilles Peskine449bd832023-01-11 14:50:10 +01002261 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002262
Gilles Peskine449bd832023-01-11 14:50:10 +01002263 if (mode == MBEDTLS_AES_DECRYPT) {
2264 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2265 if (ret != 0) {
2266 goto exit;
2267 }
2268 memcpy(buf, aes_test_xts_ct32[u], len);
2269 aes_tests = aes_test_xts_pt32[u];
2270 } else {
2271 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2272 if (ret != 0) {
2273 goto exit;
2274 }
2275 memcpy(buf, aes_test_xts_pt32[u], len);
2276 aes_tests = aes_test_xts_ct32[u];
2277 }
2278
2279
2280 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2281 buf, buf);
2282 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002283 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002284 }
2285
2286 if (memcmp(buf, aes_tests, len) != 0) {
2287 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002288 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002289 }
2290
2291 if (verbose != 0) {
2292 mbedtls_printf("passed\n");
2293 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002294 }
2295
Gilles Peskine449bd832023-01-11 14:50:10 +01002296 if (verbose != 0) {
2297 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002298 }
2299
Gilles Peskine449bd832023-01-11 14:50:10 +01002300 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002301 }
2302#endif /* MBEDTLS_CIPHER_MODE_XTS */
2303
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002304 ret = 0;
2305
2306exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002307 if (ret != 0 && verbose != 0) {
2308 mbedtls_printf("failed\n");
2309 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002310
Gilles Peskine449bd832023-01-11 14:50:10 +01002311 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002312
Gilles Peskine449bd832023-01-11 14:50:10 +01002313 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002314}
2315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002316#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002317
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002318#endif /* MBEDTLS_AES_C */