blob: b604cb75c5797c6e93add302054d64abcf1632a1 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010022 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000023 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Jerry Yuba42b072023-08-10 12:53:26 +080037#if defined(__aarch64__)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yue62ff092023-08-16 14:15:00 +080043#if defined(__amd64__) || defined(__x86_64__) || \
Jerry Yu372f7a02023-08-18 17:26:25 +080044 ((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))
Jerry Yu02b15192023-04-23 14:43:19 +080045#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080046#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080047#endif
48#endif
49
Jerry Yue62ff092023-08-16 14:15:00 +080050#if defined(__i386__) || defined(_M_IX86)
51#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
52#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080053#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080054
Jerry Yu61fc5ed2023-08-18 17:28:48 +080055#if defined(MBEDTLS_PADLOCK_C)
56#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080057#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
58#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080059#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
60#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
61 "MBEDTLS_PADLOCK_C is set"
62#endif
63#endif
Jerry Yu02b15192023-04-23 14:43:19 +080064#endif
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000067#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000068#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000070#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010071#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080072#if defined(MBEDTLS_AESCE_C)
73#include "aesce.h"
74#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000075
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000076#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020079
Jerry Yu9e628622023-08-17 11:20:09 +080080#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000081static int aes_padlock_ace = -1;
82#endif
83
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000085/*
86 * Forward S-box
87 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010088#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
Yanray Wang78ee0c92023-05-15 11:23:50 +080089 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY))
Paul Bakker5121ce52009-01-03 21:22:43 +000090static const unsigned char FSb[256] =
91{
92 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
93 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
94 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
95 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
96 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
97 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
98 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
99 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
100 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
101 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
102 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
103 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
104 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
105 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
106 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
107 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
108 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
109 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
110 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
111 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
112 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
113 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
114 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
115 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
116 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
117 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
118 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
119 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
120 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
121 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
122 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
123 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
124};
Yanray Wang422a77f2023-07-07 10:12:05 +0800125#endif /* !MBEDTLS_AES_ENCRYPT_ALT || !MBEDTLS_AES_SETKEY_ENC_ALT ||
Yanray Wang78ee0c92023-05-15 11:23:50 +0800126 (!MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000127
128/*
129 * Forward tables
130 */
131#define FT \
132\
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
134 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
135 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
136 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
137 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
138 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
139 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
140 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
141 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
142 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
143 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
144 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
145 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
146 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
147 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
148 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
149 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
150 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
151 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
152 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
153 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
154 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
155 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
156 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
157 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
158 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
159 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
160 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
161 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
162 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
163 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
164 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
165 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
166 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
167 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
168 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
169 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
170 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
171 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
172 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
173 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
174 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
175 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
176 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
177 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
178 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
179 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
180 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
181 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
182 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
183 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
184 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
185 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
186 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
187 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
188 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
189 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
190 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
191 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
192 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
193 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
194 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
195 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
196 V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100198#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100199#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000201#undef V
202
Hanno Beckerad049a92017-06-19 16:31:54 +0100203#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000206static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000207#undef V
208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000210static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000211#undef V
212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000215#undef V
216
Hanno Becker177d3cf2017-06-07 15:52:48 +0100217#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200218
Yanray Wang422a77f2023-07-07 10:12:05 +0800219#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
Dave Rodgman1be24632023-06-29 12:01:24 +0100220
Paul Bakker5121ce52009-01-03 21:22:43 +0000221#undef FT
222
Yanray Wang78ee0c92023-05-15 11:23:50 +0800223#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000224/*
225 * Reverse S-box
226 */
227static const unsigned char RSb[256] =
228{
229 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
230 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
231 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
232 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
233 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
234 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
235 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
236 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
237 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
238 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
239 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
240 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
241 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
242 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
243 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
244 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
245 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
246 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
247 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
248 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
249 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
250 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
251 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
252 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
253 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
254 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
255 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
256 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
257 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
258 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
259 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
260 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
261};
Yanray Wang78ee0c92023-05-15 11:23:50 +0800262#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264/*
265 * Reverse tables
266 */
267#define RT \
268\
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
270 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
271 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
272 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
273 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
274 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
275 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
276 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
277 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
278 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
279 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
280 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
281 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
282 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
283 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
284 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
285 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
286 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
287 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
288 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
289 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
290 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
291 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
292 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
293 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
294 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
295 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
296 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
297 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
298 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
299 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
300 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
301 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
302 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
303 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
304 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
305 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
306 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
307 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
308 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
309 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
310 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
311 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
312 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
313 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
314 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
315 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
316 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
317 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
318 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
319 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
320 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
321 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
322 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
323 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
324 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
325 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
326 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
327 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
328 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
329 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
330 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
331 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
332 V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
Yanray Wang78ee0c92023-05-15 11:23:50 +0800334#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) && \
335 !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000338static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000339#undef V
340
Hanno Beckerad049a92017-06-19 16:31:54 +0100341#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000344static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000345#undef V
346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000349#undef V
350
Gilles Peskine449bd832023-01-11 14:50:10 +0100351#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000352static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000353#undef V
354
Hanno Becker177d3cf2017-06-07 15:52:48 +0100355#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang78ee0c92023-05-15 11:23:50 +0800356#endif /* (!MBEDTLS_AES_DECRYPT_ALT || !MBEDTLS_AES_SETKEY_DEC_ALT) &&
357 !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800358
Paul Bakker5121ce52009-01-03 21:22:43 +0000359#undef RT
360
Dave Rodgman34152a42023-06-27 18:31:24 +0100361#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000362/*
363 * Round constants
364 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000365static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000366{
367 0x00000001, 0x00000002, 0x00000004, 0x00000008,
368 0x00000010, 0x00000020, 0x00000040, 0x00000080,
369 0x0000001B, 0x00000036
370};
Yanray Wang422a77f2023-07-07 10:12:05 +0800371#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000372
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
375/*
376 * Forward S-box & tables
377 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100378#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
Yanray Wang78ee0c92023-05-15 11:23:50 +0800379 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY))
Paul Bakker5121ce52009-01-03 21:22:43 +0000380static unsigned char FSb[256];
Yanray Wang422a77f2023-07-07 10:12:05 +0800381#endif /* !MBEDTLS_AES_ENCRYPT_ALT || !MBEDTLS_AES_SETKEY_ENC_ALT ||
Yanray Wang78ee0c92023-05-15 11:23:50 +0800382 (!MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100383#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200384static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100385#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200386static uint32_t FT1[256];
387static uint32_t FT2[256];
388static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100389#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang422a77f2023-07-07 10:12:05 +0800390#endif /* !MBEDTLS_AES_ENCRYPT_ALT || !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
392/*
393 * Reverse S-box & tables
394 */
Yanray Wang78ee0c92023-05-15 11:23:50 +0800395#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) && !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && \
396 !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000397static unsigned char RSb[256];
Yanray Wang78ee0c92023-05-15 11:23:50 +0800398#else /* !MBEDTLS_AES_SETKEY_ENC_ALT && !MBEDTLS_AES_SETKEY_DEC_ALT &&
399 !MBEDTLS_CIPHER_ENCRYPT_ONLY */
400#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Yanray Wang42742472023-07-07 17:28:24 +0800401static unsigned char RSb[256];
Yanray Wang78ee0c92023-05-15 11:23:50 +0800402#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY*/
403#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT && !MBEDTLS_AES_SETKEY_DEC_ALT &&
404 !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100405
Yanray Wang78ee0c92023-05-15 11:23:50 +0800406#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) && \
407 !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000408static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100409#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000410static uint32_t RT1[256];
411static uint32_t RT2[256];
412static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100413#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang78ee0c92023-05-15 11:23:50 +0800414#endif /* (!MBEDTLS_AES_DECRYPT_ALT || !MBEDTLS_AES_SETKEY_DEC_ALT) &&
415 !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
Dave Rodgman8c753f92023-06-27 18:16:13 +0100417#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000418/*
419 * Round constants
420 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000421static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
423/*
424 * Tables generation code
425 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100426#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
427#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
428#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430static int aes_init_done = 0;
431
Gilles Peskine449bd832023-01-11 14:50:10 +0100432static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000433{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800434 int i;
435 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800436 uint8_t pow[256];
437 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
439 /*
440 * compute pow and log tables over GF(2^8)
441 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000443 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800444 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800445 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 }
447
448 /*
449 * calculate the round constants
450 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800452 RCON[i] = x;
453 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000454 }
455
456 /*
457 * generate the forward and reverse S-boxes
458 */
459 FSb[0x00] = 0x63;
Yanray Wang78ee0c92023-05-15 11:23:50 +0800460#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) && \
461 !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000462 RSb[0x63] = 0x00;
Yanray Wang78ee0c92023-05-15 11:23:50 +0800463#endif /* (!MBEDTLS_AES_DECRYPT_ALT || !MBEDTLS_AES_SETKEY_DEC_ALT) &&
464 !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000467 x = pow[255 - log[i]];
468
Yanray Wangfe944ce2023-06-26 18:16:01 +0800469 y = x; y = (y << 1) | (y >> 7);
470 x ^= y; y = (y << 1) | (y >> 7);
471 x ^= y; y = (y << 1) | (y >> 7);
472 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000473 x ^= y ^ 0x63;
474
Yanray Wangfe944ce2023-06-26 18:16:01 +0800475 FSb[i] = x;
Yanray Wang78ee0c92023-05-15 11:23:50 +0800476#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) && \
477 !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000478 RSb[x] = (unsigned char) i;
Yanray Wang78ee0c92023-05-15 11:23:50 +0800479#endif /* (!MBEDTLS_AES_DECRYPT_ALT || !MBEDTLS_AES_SETKEY_DEC_ALT) &&
480 !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000481 }
482
483 /*
484 * generate the forward and reverse tables
485 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000487 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800488 y = XTIME(x);
489 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491 FT0[i] = ((uint32_t) y) ^
492 ((uint32_t) x << 8) ^
493 ((uint32_t) x << 16) ^
494 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
Hanno Beckerad049a92017-06-19 16:31:54 +0100496#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 FT1[i] = ROTL8(FT0[i]);
498 FT2[i] = ROTL8(FT1[i]);
499 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100500#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
Yanray Wang78ee0c92023-05-15 11:23:50 +0800502#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) && \
503 !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000504 x = RSb[i];
505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
507 ((uint32_t) MUL(0x09, x) << 8) ^
508 ((uint32_t) MUL(0x0D, x) << 16) ^
509 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
Hanno Beckerad049a92017-06-19 16:31:54 +0100511#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100512 RT1[i] = ROTL8(RT0[i]);
513 RT2[i] = ROTL8(RT1[i]);
514 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100515#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang78ee0c92023-05-15 11:23:50 +0800516#endif /* (!MBEDTLS_AES_DECRYPT_ALT || !MBEDTLS_AES_SETKEY_DEC_ALT) &&
517 !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 }
519}
520
Yanray Wang422a77f2023-07-07 10:12:05 +0800521#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Dave Rodgman8c753f92023-06-27 18:16:13 +0100522
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200523#undef ROTL8
524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
Hanno Beckerad049a92017-06-19 16:31:54 +0100527#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
530#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
531#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200532
533#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100534#define AES_RT1(idx) ROTL8(RT0[idx])
535#define AES_RT2(idx) ROTL16(RT0[idx])
536#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200537
538#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100539#define AES_FT1(idx) ROTL8(FT0[idx])
540#define AES_FT2(idx) ROTL16(FT0[idx])
541#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200542
Hanno Becker177d3cf2017-06-07 15:52:48 +0100543#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200544
545#define AES_RT0(idx) RT0[idx]
546#define AES_RT1(idx) RT1[idx]
547#define AES_RT2(idx) RT2[idx]
548#define AES_RT3(idx) RT3[idx]
549
550#define AES_FT0(idx) FT0[idx]
551#define AES_FT1(idx) FT1[idx]
552#define AES_FT2(idx) FT2[idx]
553#define AES_FT3(idx) FT3[idx]
554
Hanno Becker177d3cf2017-06-07 15:52:48 +0100555#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200558{
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200560}
561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200563{
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200565 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200567
Gilles Peskine449bd832023-01-11 14:50:10 +0100568 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200569}
570
Jaeden Amero9366feb2018-05-29 18:55:17 +0100571#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100572void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100573{
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 mbedtls_aes_init(&ctx->crypt);
575 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100576}
577
Gilles Peskine449bd832023-01-11 14:50:10 +0100578void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100579{
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100581 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100582 }
Simon Butcher5201e412018-12-06 17:40:14 +0000583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 mbedtls_aes_free(&ctx->crypt);
585 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100586}
587#endif /* MBEDTLS_CIPHER_MODE_XTS */
588
Gilles Peskine0de8f852023-03-16 17:14:59 +0100589/* Some implementations need the round keys to be aligned.
590 * Return an offset to be added to buf, such that (buf + offset) is
591 * correctly aligned.
592 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
593 * i.e. an offset of 1 means 4 bytes and so on.
594 */
Jerry Yu96084472023-08-17 18:10:45 +0800595#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100596 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100597#define MAY_NEED_TO_ALIGN
598#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100599
Yanray Wang78ee0c92023-05-15 11:23:50 +0800600#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
601 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY))
Gilles Peskine0de8f852023-03-16 17:14:59 +0100602static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
603{
604#if defined(MAY_NEED_TO_ALIGN)
605 int align_16_bytes = 0;
606
Jerry Yu9e628622023-08-17 11:20:09 +0800607#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100608 if (aes_padlock_ace == -1) {
609 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
610 }
611 if (aes_padlock_ace) {
612 align_16_bytes = 1;
613 }
614#endif
615
Gilles Peskine9c682e72023-03-16 17:21:33 +0100616#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100617 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
618 align_16_bytes = 1;
619 }
620#endif
621
622 if (align_16_bytes) {
623 /* These implementations needs 16-byte alignment
624 * for the round key array. */
625 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
626 if (delta == 0) {
627 return 0;
628 } else {
629 return 4 - delta; // 16 bytes = 4 uint32_t
630 }
631 }
632#else /* MAY_NEED_TO_ALIGN */
633 (void) buf;
634#endif /* MAY_NEED_TO_ALIGN */
635
636 return 0;
637}
Yanray Wang78ee0c92023-05-15 11:23:50 +0800638#endif /* MAY_NEED_TO_ALIGN || !MBEDTLS_AES_SETKEY_ENC_ALT ||
639 (!MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100640
Paul Bakker5121ce52009-01-03 21:22:43 +0000641/*
642 * AES key schedule (encryption)
643 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200644#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100645int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
646 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000647{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000648 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800652#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 case 192: ctx->nr = 12; break;
654 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800655#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 }
658
Simon Butcher5201e412018-12-06 17:40:14 +0000659#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000661 aes_gen_tables();
662 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000663 }
664#endif
665
Gilles Peskine0de8f852023-03-16 17:14:59 +0100666 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100667 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100669#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
671 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
672 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100673#endif
674
Jerry Yu3f2fb712023-01-10 17:05:42 +0800675#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100676 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800677 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
678 }
679#endif
680
Jerry Yu29c91ba2023-08-04 11:02:04 +0800681#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800682 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000684 }
685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000687 case 10:
688
Jerry Yu3a0f0442023-08-17 17:06:21 +0800689 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000690 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
692 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
693 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
694 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
696 RK[5] = RK[1] ^ RK[4];
697 RK[6] = RK[2] ^ RK[5];
698 RK[7] = RK[3] ^ RK[6];
699 }
700 break;
701
Arto Kinnunen732ca322023-04-14 14:26:10 +0800702#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 case 12:
704
Jerry Yu3a0f0442023-08-17 17:06:21 +0800705 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000706 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
708 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
709 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
710 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
712 RK[7] = RK[1] ^ RK[6];
713 RK[8] = RK[2] ^ RK[7];
714 RK[9] = RK[3] ^ RK[8];
715 RK[10] = RK[4] ^ RK[9];
716 RK[11] = RK[5] ^ RK[10];
717 }
718 break;
719
720 case 14:
721
Jerry Yu3a0f0442023-08-17 17:06:21 +0800722 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000723 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
725 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
726 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
727 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000728
729 RK[9] = RK[1] ^ RK[8];
730 RK[10] = RK[2] ^ RK[9];
731 RK[11] = RK[3] ^ RK[10];
732
733 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
735 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
736 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
737 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000738
739 RK[13] = RK[5] ^ RK[12];
740 RK[14] = RK[6] ^ RK[13];
741 RK[15] = RK[7] ^ RK[14];
742 }
743 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800744#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000745 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800748#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000749}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200750#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
752/*
753 * AES key schedule (decryption)
754 */
Yanray Wang78ee0c92023-05-15 11:23:50 +0800755#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100756int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
757 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000758{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800759#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800760 uint32_t *SK;
761#endif
762 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000764 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800765
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
Gilles Peskine0de8f852023-03-16 17:14:59 +0100769 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100770 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000771
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200772 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200774 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000776
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200777 ctx->nr = cty.nr;
778
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100779#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
781 mbedtls_aesni_inverse_key((unsigned char *) RK,
782 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200783 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100784 }
785#endif
786
Jerry Yue096da12023-01-10 17:07:01 +0800787#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100788 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800789 mbedtls_aesce_inverse_key(
790 (unsigned char *) RK,
791 (const unsigned char *) (cty.buf + cty.rk_offset),
792 ctx->nr);
793 goto exit;
794 }
795#endif
796
Jerry Yu29c91ba2023-08-04 11:02:04 +0800797#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100798 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000799
800 *RK++ = *SK++;
801 *RK++ = *SK++;
802 *RK++ = *SK++;
803 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800804 SK -= 8;
805 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
806 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
808 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
809 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
810 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000811 }
812 }
813
814 *RK++ = *SK++;
815 *RK++ = *SK++;
816 *RK++ = *SK++;
817 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800818#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200819exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000823}
Yanray Wang78ee0c92023-05-15 11:23:50 +0800824#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100825
826#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100827static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
828 unsigned int keybits,
829 const unsigned char **key1,
830 unsigned int *key1bits,
831 const unsigned char **key2,
832 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100833{
834 const unsigned int half_keybits = keybits / 2;
835 const unsigned int half_keybytes = half_keybits / 8;
836
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100838 case 256: break;
839 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100841 }
842
843 *key1bits = half_keybits;
844 *key2bits = half_keybits;
845 *key1 = &key[0];
846 *key2 = &key[half_keybytes];
847
848 return 0;
849}
850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
852 const unsigned char *key,
853 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100854{
Janos Follath24eed8d2019-11-22 13:21:35 +0000855 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100856 const unsigned char *key1, *key2;
857 unsigned int key1bits, key2bits;
858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
860 &key2, &key2bits);
861 if (ret != 0) {
862 return ret;
863 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100864
865 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
867 if (ret != 0) {
868 return ret;
869 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100870
871 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100873}
874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
876 const unsigned char *key,
877 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100878{
Janos Follath24eed8d2019-11-22 13:21:35 +0000879 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100880 const unsigned char *key1, *key2;
881 unsigned int key1bits, key2bits;
882
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
884 &key2, &key2bits);
885 if (ret != 0) {
886 return ret;
887 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100888
889 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
891 if (ret != 0) {
892 return ret;
893 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100894
895 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100897}
898#endif /* MBEDTLS_CIPHER_MODE_XTS */
899
Gilles Peskine449bd832023-01-11 14:50:10 +0100900#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100901 do \
902 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
904 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
905 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
906 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100907 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
909 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
910 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
911 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100912 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
914 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
915 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
916 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100917 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
919 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
920 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
921 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
922 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
Gilles Peskine449bd832023-01-11 14:50:10 +0100924#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100925 do \
926 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
928 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
929 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
930 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100931 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
933 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
934 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
935 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100936 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
938 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
939 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
940 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100941 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
943 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
944 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
945 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
946 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000947
948/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200949 * AES-ECB block encryption
950 */
951#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100952int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
953 const unsigned char input[16],
954 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955{
956 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100957 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200959 uint32_t X[4];
960 uint32_t Y[4];
961 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
964 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
965 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
966 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
969 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]);
970 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 +0200971 }
972
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 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 +0200974
Gilles Peskine5197c662020-08-26 17:03:24 +0200975 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
977 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
978 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
979 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200980
Gilles Peskine5197c662020-08-26 17:03:24 +0200981 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
983 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
984 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
985 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986
Gilles Peskine5197c662020-08-26 17:03:24 +0200987 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
989 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
990 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
991 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992
Gilles Peskine5197c662020-08-26 17:03:24 +0200993 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
995 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
996 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
997 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1000 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1001 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1002 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001007}
1008#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
1009
1010/*
1011 * AES-ECB block decryption
1012 */
Yanray Wang78ee0c92023-05-15 11:23:50 +08001013#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001014int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
1015 const unsigned char input[16],
1016 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001017{
1018 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +01001019 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001021 uint32_t X[4];
1022 uint32_t Y[4];
1023 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1026 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1027 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1028 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001029
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1031 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]);
1032 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 +02001033 }
1034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 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 +02001036
Gilles Peskine5197c662020-08-26 17:03:24 +02001037 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1039 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1040 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1041 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001042
Gilles Peskine5197c662020-08-26 17:03:24 +02001043 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1045 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1046 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1047 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001048
Gilles Peskine5197c662020-08-26 17:03:24 +02001049 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1051 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1052 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1053 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001054
Gilles Peskine5197c662020-08-26 17:03:24 +02001055 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1057 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1058 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1059 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001060
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1062 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1063 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1064 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001067
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001069}
Yanray Wang78ee0c92023-05-15 11:23:50 +08001070#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_CIPHER_ENCRYPT_ONLY */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001071
Gilles Peskine0de8f852023-03-16 17:14:59 +01001072#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001073/* VIA Padlock and our intrinsics-based implementation of AESNI require
1074 * the round keys to be aligned on a 16-byte boundary. We take care of this
1075 * before creating them, but the AES context may have moved (this can happen
1076 * if the library is called from a language with managed memory), and in later
1077 * calls it might have a different alignment with respect to 16-byte memory.
1078 * So we may need to realign.
1079 */
1080static void aes_maybe_realign(mbedtls_aes_context *ctx)
1081{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001082 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1083 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001084 memmove(ctx->buf + new_offset, // new address
1085 ctx->buf + ctx->rk_offset, // current address
1086 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1087 ctx->rk_offset = new_offset;
1088 }
1089}
1090#endif
1091
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001092/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001093 * AES-ECB block encryption/decryption
1094 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001095int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1096 int mode,
1097 const unsigned char input[16],
1098 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001099{
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001101 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001103
Gilles Peskine0de8f852023-03-16 17:14:59 +01001104#if defined(MAY_NEED_TO_ALIGN)
1105 aes_maybe_realign(ctx);
1106#endif
1107
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001108#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001109 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1110 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1111 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001112#endif
1113
Jerry Yu2bb3d812023-01-10 17:38:26 +08001114#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001115 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001116 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1117 }
1118#endif
1119
Jerry Yu9e628622023-08-17 11:20:09 +08001120#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001122 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001123 }
1124#endif
1125
Jerry Yu29c91ba2023-08-04 11:02:04 +08001126#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001127#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 if (mode == MBEDTLS_AES_ENCRYPT) {
1129 return mbedtls_internal_aes_encrypt(ctx, input, output);
1130 } else {
1131 return mbedtls_internal_aes_decrypt(ctx, input, output);
1132 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001133#else
1134 return mbedtls_internal_aes_encrypt(ctx, input, output);
Jerry Yu29c91ba2023-08-04 11:02:04 +08001135#endif
Yanray Wang78ee0c92023-05-15 11:23:50 +08001136#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001137}
1138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001139#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001140
Paul Bakker5121ce52009-01-03 21:22:43 +00001141/*
1142 * AES-CBC buffer encryption/decryption
1143 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001144int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1145 int mode,
1146 size_t length,
1147 unsigned char iv[16],
1148 const unsigned char *input,
1149 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001150{
Gilles Peskine7820a572021-07-07 21:08:28 +02001151 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001152 unsigned char temp[16];
1153
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001155 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001157
Paul Elliott2ad93672023-08-11 11:07:06 +01001158 /* Nothing to do if length is zero. */
1159 if (length == 0) {
1160 return 0;
1161 }
1162
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 if (length % 16) {
1164 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1165 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001166
Jerry Yu9e628622023-08-17 11:20:09 +08001167#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 if (aes_padlock_ace > 0) {
1169 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1170 return 0;
1171 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001172
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001173 // If padlock data misaligned, we just fall back to
1174 // unaccelerated mode
1175 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001176 }
1177#endif
1178
Dave Rodgman906c63c2023-06-14 17:53:51 +01001179 const unsigned char *ivp = iv;
1180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 if (mode == MBEDTLS_AES_DECRYPT) {
1182 while (length > 0) {
1183 memcpy(temp, input, 16);
1184 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1185 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001186 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001188 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001189 * the result for the next block in CBC, and the cost of transferring that data from
1190 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001191 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001192
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001194
1195 input += 16;
1196 output += 16;
1197 length -= 16;
1198 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001199 } else {
1200 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001201 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001202
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1204 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001205 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001206 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001207 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001208
1209 input += 16;
1210 output += 16;
1211 length -= 16;
1212 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001213 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001214 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001215 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001216
Gilles Peskine7820a572021-07-07 21:08:28 +02001217exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001219}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001220#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001221
Aorimn5f778012016-06-09 23:22:58 +02001222#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001223
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001224typedef unsigned char mbedtls_be128[16];
1225
1226/*
1227 * GF(2^128) multiplication function
1228 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001229 * This function multiplies a field element by x in the polynomial field
1230 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001231 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001232 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001233 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001234#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001235MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001236#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001237static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001238 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001239{
1240 uint64_t a, b, ra, rb;
1241
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 a = MBEDTLS_GET_UINT64_LE(x, 0);
1243 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001244
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1246 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001247
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1249 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001250}
1251
Aorimn5f778012016-06-09 23:22:58 +02001252/*
1253 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001254 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001255 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001256 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001257 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001258#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001259MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001260#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001261int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1262 int mode,
1263 size_t length,
1264 const unsigned char data_unit[16],
1265 const unsigned char *input,
1266 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001267{
Janos Follath24eed8d2019-11-22 13:21:35 +00001268 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001269 size_t blocks = length / 16;
1270 size_t leftover = length % 16;
1271 unsigned char tweak[16];
1272 unsigned char prev_tweak[16];
1273 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001274
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001276 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001278
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001279 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 }
Aorimn5f778012016-06-09 23:22:58 +02001283
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001284 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001286 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 }
Aorimn5f778012016-06-09 23:22:58 +02001288
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1291 data_unit, tweak);
1292 if (ret != 0) {
1293 return ret;
1294 }
Aorimn5f778012016-06-09 23:22:58 +02001295
Gilles Peskine449bd832023-01-11 14:50:10 +01001296 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001297 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001298 /* We are on the last block in a decrypt operation that has
1299 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001300 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001301 * the leftovers and then update the current tweak for use on this,
1302 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001303 memcpy(prev_tweak, tweak, sizeof(tweak));
1304 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001305 }
1306
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001308
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1310 if (ret != 0) {
1311 return ret;
1312 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001313
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001315
1316 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001318
1319 output += 16;
1320 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001321 }
1322
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001324 /* If we are on the leftover bytes in a decrypt operation, we need to
1325 * use the previous tweak for these bytes (as saved in prev_tweak). */
1326 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001327
Jaeden Amerod82cd862018-04-28 15:02:45 +01001328 /* We are now on the final part of the data unit, which doesn't divide
1329 * evenly by 16. It's time for ciphertext stealing. */
1330 size_t i;
1331 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001332
Jaeden Amerod82cd862018-04-28 15:02:45 +01001333 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001334 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001336 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001337 }
Aorimn5f778012016-06-09 23:22:58 +02001338
Dave Rodgman069e7f42022-11-24 19:37:26 +00001339 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001341
Jaeden Amerod82cd862018-04-28 15:02:45 +01001342 /* Copy ciphertext bytes from the previous block for input in this
1343 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001344 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001345
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1347 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001348 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 }
Aorimn5f778012016-06-09 23:22:58 +02001350
Jaeden Amerod82cd862018-04-28 15:02:45 +01001351 /* Write the result back to the previous block, overriding the previous
1352 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001354 }
1355
Gilles Peskine449bd832023-01-11 14:50:10 +01001356 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001357}
1358#endif /* MBEDTLS_CIPHER_MODE_XTS */
1359
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001360#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001361/*
1362 * AES-CFB128 buffer encryption/decryption
1363 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001364int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1365 int mode,
1366 size_t length,
1367 size_t *iv_off,
1368 unsigned char iv[16],
1369 const unsigned char *input,
1370 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001371{
Paul Bakker27fdf462011-06-09 13:55:13 +00001372 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001373 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001374 size_t n;
1375
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001377 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001379
1380 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001381
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 if (n > 15) {
1383 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1384 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001385
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 if (mode == MBEDTLS_AES_DECRYPT) {
1387 while (length--) {
1388 if (n == 0) {
1389 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1390 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001391 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001393 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001394
1395 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001397 iv[n] = (unsigned char) c;
1398
Gilles Peskine449bd832023-01-11 14:50:10 +01001399 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001400 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001401 } else {
1402 while (length--) {
1403 if (n == 0) {
1404 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1405 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001406 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001407 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001408 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001409
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001411
Gilles Peskine449bd832023-01-11 14:50:10 +01001412 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001413 }
1414 }
1415
1416 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001417 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001418
Gilles Peskine7820a572021-07-07 21:08:28 +02001419exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001421}
Paul Bakker556efba2014-01-24 15:38:12 +01001422
1423/*
1424 * AES-CFB8 buffer encryption/decryption
1425 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001426int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1427 int mode,
1428 size_t length,
1429 unsigned char iv[16],
1430 const unsigned char *input,
1431 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001432{
Gilles Peskine7820a572021-07-07 21:08:28 +02001433 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001434 unsigned char c;
1435 unsigned char ov[17];
1436
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001438 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001439 }
1440 while (length--) {
1441 memcpy(ov, iv, 16);
1442 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1443 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001444 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001445 }
Paul Bakker556efba2014-01-24 15:38:12 +01001446
Gilles Peskine449bd832023-01-11 14:50:10 +01001447 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001448 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001449 }
Paul Bakker556efba2014-01-24 15:38:12 +01001450
Gilles Peskine449bd832023-01-11 14:50:10 +01001451 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001452
Gilles Peskine449bd832023-01-11 14:50:10 +01001453 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001454 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001455 }
Paul Bakker556efba2014-01-24 15:38:12 +01001456
Gilles Peskine449bd832023-01-11 14:50:10 +01001457 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001458 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001459 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001460
Gilles Peskine7820a572021-07-07 21:08:28 +02001461exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001463}
Simon Butcher76a5b222018-04-22 22:57:27 +01001464#endif /* MBEDTLS_CIPHER_MODE_CFB */
1465
1466#if defined(MBEDTLS_CIPHER_MODE_OFB)
1467/*
1468 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1469 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001470int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1471 size_t length,
1472 size_t *iv_off,
1473 unsigned char iv[16],
1474 const unsigned char *input,
1475 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001476{
Simon Butcherad4e4932018-04-29 00:43:47 +01001477 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001478 size_t n;
1479
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001480 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001481
Gilles Peskine449bd832023-01-11 14:50:10 +01001482 if (n > 15) {
1483 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1484 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001485
Gilles Peskine449bd832023-01-11 14:50:10 +01001486 while (length--) {
1487 if (n == 0) {
1488 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1489 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001490 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001491 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001492 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001493 *output++ = *input++ ^ iv[n];
1494
Gilles Peskine449bd832023-01-11 14:50:10 +01001495 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001496 }
1497
1498 *iv_off = n;
1499
Simon Butcherad4e4932018-04-29 00:43:47 +01001500exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001501 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001502}
1503#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001504
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001505#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001506/*
1507 * AES-CTR buffer encryption/decryption
1508 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001509int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1510 size_t length,
1511 size_t *nc_off,
1512 unsigned char nonce_counter[16],
1513 unsigned char stream_block[16],
1514 const unsigned char *input,
1515 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001516{
Paul Bakker369e14b2012-04-18 14:16:09 +00001517 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001518 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001519 size_t n;
1520
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001521 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001522
Gilles Peskine449bd832023-01-11 14:50:10 +01001523 if (n > 0x0F) {
1524 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1525 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001526
Gilles Peskine449bd832023-01-11 14:50:10 +01001527 while (length--) {
1528 if (n == 0) {
1529 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1530 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001531 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001532 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001533
Gilles Peskine449bd832023-01-11 14:50:10 +01001534 for (i = 16; i > 0; i--) {
1535 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001536 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001537 }
1538 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001539 }
1540 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001541 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001542
Gilles Peskine449bd832023-01-11 14:50:10 +01001543 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001544 }
1545
1546 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001547 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001548
Gilles Peskine7820a572021-07-07 21:08:28 +02001549exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001550 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001551}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001552#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001554#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001556#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001557/*
1558 * AES test vectors from:
1559 *
1560 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1561 */
Yanray Wang78ee0c92023-05-15 11:23:50 +08001562#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Yanray Wang62c99912023-05-11 11:06:53 +08001563static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001564{
1565 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1566 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001567#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001568 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1569 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1570 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1571 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001572#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001573};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001574#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001575
Yanray Wang62c99912023-05-11 11:06:53 +08001576static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001577{
1578 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1579 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001580#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001581 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1582 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1583 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1584 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001585#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001586};
1587
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001588#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001589static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001590{
1591 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1592 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001593#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001594 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1595 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1596 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1597 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001598#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001599};
1600
Yanray Wang62c99912023-05-11 11:06:53 +08001601static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001602{
1603 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1604 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001605#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001606 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1607 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1608 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1609 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001610#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001611};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001613
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001614#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001615/*
1616 * AES-CFB128 test vectors from:
1617 *
1618 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1619 */
Yanray Wang62c99912023-05-11 11:06:53 +08001620static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001621{
1622 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1623 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001624#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001625 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1626 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1627 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1628 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1629 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1630 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1631 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001632#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001633};
1634
1635static const unsigned char aes_test_cfb128_iv[16] =
1636{
1637 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1638 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1639};
1640
1641static const unsigned char aes_test_cfb128_pt[64] =
1642{
1643 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1644 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1645 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1646 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1647 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1648 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1649 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1650 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1651};
1652
Yanray Wang62c99912023-05-11 11:06:53 +08001653static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001654{
1655 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1656 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1657 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1658 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1659 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1660 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1661 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1662 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001663#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001664 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1665 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1666 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1667 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1668 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1669 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1670 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1671 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1672 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1673 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1674 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1675 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1676 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1677 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1678 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1679 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001680#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001681};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001682#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001683
Simon Butcherad4e4932018-04-29 00:43:47 +01001684#if defined(MBEDTLS_CIPHER_MODE_OFB)
1685/*
1686 * AES-OFB test vectors from:
1687 *
Simon Butcher5db13622018-06-04 22:11:25 +01001688 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001689 */
Yanray Wang62c99912023-05-11 11:06:53 +08001690static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001691{
1692 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1693 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001694#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001695 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1696 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1697 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1698 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1699 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1700 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1701 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001702#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001703};
1704
1705static const unsigned char aes_test_ofb_iv[16] =
1706{
1707 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1708 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1709};
1710
1711static const unsigned char aes_test_ofb_pt[64] =
1712{
1713 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1714 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1715 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1716 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1717 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1718 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1719 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1720 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1721};
1722
Yanray Wang62c99912023-05-11 11:06:53 +08001723static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001724{
1725 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1726 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1727 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1728 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1729 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1730 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1731 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1732 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001733#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001734 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1735 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1736 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1737 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1738 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1739 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1740 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1741 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1742 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1743 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1744 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1745 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1746 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1747 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1748 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1749 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001750#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001751};
1752#endif /* MBEDTLS_CIPHER_MODE_OFB */
1753
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001754#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001755/*
1756 * AES-CTR test vectors from:
1757 *
1758 * http://www.faqs.org/rfcs/rfc3686.html
1759 */
1760
Yanray Wang62c99912023-05-11 11:06:53 +08001761static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001762{
1763 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1764 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1765 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1766 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1767 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1768 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1769};
1770
Yanray Wang62c99912023-05-11 11:06:53 +08001771static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001772{
1773 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1775 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1776 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1777 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1778 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1779};
1780
Yanray Wang62c99912023-05-11 11:06:53 +08001781static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001782{
1783 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1784 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001785 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1786 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1787 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1788 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1789
1790 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1791 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1792 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1793 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1794 0x20, 0x21, 0x22, 0x23 }
1795};
1796
Yanray Wang62c99912023-05-11 11:06:53 +08001797static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001798{
1799 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1800 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1801 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1802 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1803 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1804 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1805 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1806 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1807 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1808 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1809 0x25, 0xB2, 0x07, 0x2F }
1810};
1811
1812static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001813{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001814#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001815
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001816#if defined(MBEDTLS_CIPHER_MODE_XTS)
1817/*
1818 * AES-XTS test vectors from:
1819 *
1820 * IEEE P1619/D16 Annex B
1821 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1822 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1823 */
1824static const unsigned char aes_test_xts_key[][32] =
1825{
1826 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1829 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1830 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1831 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1832 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1833 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1834 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1835 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1836 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1837 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1838};
1839
1840static const unsigned char aes_test_xts_pt32[][32] =
1841{
1842 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1846 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1847 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1848 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1849 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1850 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1851 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1852 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1853 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1854};
1855
1856static const unsigned char aes_test_xts_ct32[][32] =
1857{
1858 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1859 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1860 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1861 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1862 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1863 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1864 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1865 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1866 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1867 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1868 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1869 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1870};
1871
1872static const unsigned char aes_test_xts_data_unit[][16] =
1873{
Gilles Peskine449bd832023-01-11 14:50:10 +01001874 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1875 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1876 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1878 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001880};
1881
1882#endif /* MBEDTLS_CIPHER_MODE_XTS */
1883
Paul Bakker5121ce52009-01-03 21:22:43 +00001884/*
1885 * Checkup routine
1886 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001887int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001888{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001889 int ret = 0, i, j, u, mode;
1890 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001891 unsigned char key[32];
1892 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001893 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001894#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1895 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001896 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001897#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001898#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001899 unsigned char prv[16];
1900#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001901#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1902 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001903 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001904#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001905#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001906 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001907#endif
1908#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001909 unsigned char nonce_counter[16];
1910 unsigned char stream_block[16];
1911#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001912 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001913
Gilles Peskine449bd832023-01-11 14:50:10 +01001914 memset(key, 0, 32);
1915 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001916
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001917 if (verbose != 0) {
1918#if defined(MBEDTLS_AES_ALT)
1919 mbedtls_printf(" AES note: alternative implementation.\n");
1920#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001921#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001922#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001923 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001924#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001925 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001926#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001927#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001928#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001929 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1930 mbedtls_printf(" AES note: using AESNI.\n");
1931 } else
1932#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001933#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001934 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1935 mbedtls_printf(" AES note: using VIA Padlock.\n");
1936 } else
1937#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001938#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001939 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001940 mbedtls_printf(" AES note: using AESCE.\n");
1941 } else
1942#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001943 {
1944#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1945 mbedtls_printf(" AES note: built-in implementation.\n");
1946#endif
1947 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001948#endif /* MBEDTLS_AES_ALT */
1949 }
1950
Paul Bakker5121ce52009-01-03 21:22:43 +00001951 /*
1952 * ECB mode
1953 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001954 {
1955 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001956 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001957
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001958 for (i = 0; i < num_tests << 1; i++) {
1959 u = i >> 1;
1960 keybits = 128 + u * 64;
1961 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001962
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001963 if (verbose != 0) {
1964 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1965 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1966 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001967#if defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
1968 if (mode == MBEDTLS_AES_DECRYPT) {
1969 if (verbose != 0) {
1970 mbedtls_printf("skipped\n");
1971 }
1972 continue;
1973 }
1974#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001975
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001976 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001977
Yanray Wang78ee0c92023-05-15 11:23:50 +08001978#if !defined(MBEDTLS_CIPHER_ENCRYPT_ONLY)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001979 if (mode == MBEDTLS_AES_DECRYPT) {
1980 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1981 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001982 } else
1983#endif
1984 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001985 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1986 aes_tests = aes_test_ecb_enc[u];
1987 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001988
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001989 /*
1990 * AES-192 is an optional feature that may be unavailable when
1991 * there is an alternative underlying implementation i.e. when
1992 * MBEDTLS_AES_ALT is defined.
1993 */
1994 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1995 mbedtls_printf("skipped\n");
1996 continue;
1997 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001998 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001999 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002000
2001 for (j = 0; j < 10000; j++) {
2002 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
2003 if (ret != 0) {
2004 goto exit;
2005 }
2006 }
2007
2008 if (memcmp(buf, aes_tests, 16) != 0) {
2009 ret = 1;
2010 goto exit;
2011 }
2012
2013 if (verbose != 0) {
2014 mbedtls_printf("passed\n");
2015 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002016 }
2017
Gilles Peskine449bd832023-01-11 14:50:10 +01002018 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002019 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002020 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002021 }
2022
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002023#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00002024 /*
2025 * CBC mode
2026 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002027 {
2028 static const int num_tests =
2029 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00002030
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002031 for (i = 0; i < num_tests << 1; i++) {
2032 u = i >> 1;
2033 keybits = 128 + u * 64;
2034 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01002035
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002036 if (verbose != 0) {
2037 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2038 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002039 }
2040
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002041 memset(iv, 0, 16);
2042 memset(prv, 0, 16);
2043 memset(buf, 0, 16);
2044
2045 if (mode == MBEDTLS_AES_DECRYPT) {
2046 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2047 aes_tests = aes_test_cbc_dec[u];
2048 } else {
2049 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2050 aes_tests = aes_test_cbc_enc[u];
2051 }
2052
2053 /*
2054 * AES-192 is an optional feature that may be unavailable when
2055 * there is an alternative underlying implementation i.e. when
2056 * MBEDTLS_AES_ALT is defined.
2057 */
2058 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2059 mbedtls_printf("skipped\n");
2060 continue;
2061 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002062 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002063 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002064
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002065 for (j = 0; j < 10000; j++) {
2066 if (mode == MBEDTLS_AES_ENCRYPT) {
2067 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002068
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002069 memcpy(tmp, prv, 16);
2070 memcpy(prv, buf, 16);
2071 memcpy(buf, tmp, 16);
2072 }
2073
2074 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2075 if (ret != 0) {
2076 goto exit;
2077 }
2078
2079 }
2080
2081 if (memcmp(buf, aes_tests, 16) != 0) {
2082 ret = 1;
2083 goto exit;
2084 }
2085
2086 if (verbose != 0) {
2087 mbedtls_printf("passed\n");
2088 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002089 }
2090
Gilles Peskine449bd832023-01-11 14:50:10 +01002091 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002092 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002093 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002094 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002095#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002096
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002098 /*
2099 * CFB128 mode
2100 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002101 {
2102 static const int num_tests =
2103 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002104
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002105 for (i = 0; i < num_tests << 1; i++) {
2106 u = i >> 1;
2107 keybits = 128 + u * 64;
2108 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002109
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002110 if (verbose != 0) {
2111 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2112 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2113 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002114
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002115 memcpy(iv, aes_test_cfb128_iv, 16);
2116 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002117
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002118 offset = 0;
2119 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2120 /*
2121 * AES-192 is an optional feature that may be unavailable when
2122 * there is an alternative underlying implementation i.e. when
2123 * MBEDTLS_AES_ALT is defined.
2124 */
2125 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2126 mbedtls_printf("skipped\n");
2127 continue;
2128 } else if (ret != 0) {
2129 goto exit;
2130 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002131
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002132 if (mode == MBEDTLS_AES_DECRYPT) {
2133 memcpy(buf, aes_test_cfb128_ct[u], 64);
2134 aes_tests = aes_test_cfb128_pt;
2135 } else {
2136 memcpy(buf, aes_test_cfb128_pt, 64);
2137 aes_tests = aes_test_cfb128_ct[u];
2138 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002139
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002140 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2141 if (ret != 0) {
2142 goto exit;
2143 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002144
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002145 if (memcmp(buf, aes_tests, 64) != 0) {
2146 ret = 1;
2147 goto exit;
2148 }
2149
2150 if (verbose != 0) {
2151 mbedtls_printf("passed\n");
2152 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002153 }
2154
Gilles Peskine449bd832023-01-11 14:50:10 +01002155 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002156 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002157 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002158 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002159#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002160
Simon Butcherad4e4932018-04-29 00:43:47 +01002161#if defined(MBEDTLS_CIPHER_MODE_OFB)
2162 /*
2163 * OFB mode
2164 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002165 {
2166 static const int num_tests =
2167 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002168
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002169 for (i = 0; i < num_tests << 1; i++) {
2170 u = i >> 1;
2171 keybits = 128 + u * 64;
2172 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002173
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002174 if (verbose != 0) {
2175 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2176 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2177 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002178
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002179 memcpy(iv, aes_test_ofb_iv, 16);
2180 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002181
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002182 offset = 0;
2183 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2184 /*
2185 * AES-192 is an optional feature that may be unavailable when
2186 * there is an alternative underlying implementation i.e. when
2187 * MBEDTLS_AES_ALT is defined.
2188 */
2189 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2190 mbedtls_printf("skipped\n");
2191 continue;
2192 } else if (ret != 0) {
2193 goto exit;
2194 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 if (mode == MBEDTLS_AES_DECRYPT) {
2197 memcpy(buf, aes_test_ofb_ct[u], 64);
2198 aes_tests = aes_test_ofb_pt;
2199 } else {
2200 memcpy(buf, aes_test_ofb_pt, 64);
2201 aes_tests = aes_test_ofb_ct[u];
2202 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002203
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002204 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2205 if (ret != 0) {
2206 goto exit;
2207 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002208
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002209 if (memcmp(buf, aes_tests, 64) != 0) {
2210 ret = 1;
2211 goto exit;
2212 }
2213
2214 if (verbose != 0) {
2215 mbedtls_printf("passed\n");
2216 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002217 }
2218
Gilles Peskine449bd832023-01-11 14:50:10 +01002219 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002220 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002221 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002222 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002223#endif /* MBEDTLS_CIPHER_MODE_OFB */
2224
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002225#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002226 /*
2227 * CTR mode
2228 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002229 {
2230 static const int num_tests =
2231 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002232
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002233 for (i = 0; i < num_tests << 1; i++) {
2234 u = i >> 1;
2235 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002236
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002237 if (verbose != 0) {
2238 mbedtls_printf(" AES-CTR-128 (%s): ",
2239 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2240 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002241
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002242 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2243 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002244
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002245 offset = 0;
2246 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2247 goto exit;
2248 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002249
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002250 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002251
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002252 if (mode == MBEDTLS_AES_DECRYPT) {
2253 memcpy(buf, aes_test_ctr_ct[u], len);
2254 aes_tests = aes_test_ctr_pt[u];
2255 } else {
2256 memcpy(buf, aes_test_ctr_pt[u], len);
2257 aes_tests = aes_test_ctr_ct[u];
2258 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002259
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002260 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2261 stream_block, buf, buf);
2262 if (ret != 0) {
2263 goto exit;
2264 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002265
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002266 if (memcmp(buf, aes_tests, len) != 0) {
2267 ret = 1;
2268 goto exit;
2269 }
2270
2271 if (verbose != 0) {
2272 mbedtls_printf("passed\n");
2273 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002274 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002275 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002276
Gilles Peskine449bd832023-01-11 14:50:10 +01002277 if (verbose != 0) {
2278 mbedtls_printf("\n");
2279 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002280#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002281
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002282#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002283 /*
2284 * XTS mode
2285 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002286 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002287 static const int num_tests =
2288 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2289 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002290
Gilles Peskine449bd832023-01-11 14:50:10 +01002291 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002292
Gilles Peskine449bd832023-01-11 14:50:10 +01002293 for (i = 0; i < num_tests << 1; i++) {
2294 const unsigned char *data_unit;
2295 u = i >> 1;
2296 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002297
Gilles Peskine449bd832023-01-11 14:50:10 +01002298 if (verbose != 0) {
2299 mbedtls_printf(" AES-XTS-128 (%s): ",
2300 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2301 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002302
Gilles Peskine449bd832023-01-11 14:50:10 +01002303 memset(key, 0, sizeof(key));
2304 memcpy(key, aes_test_xts_key[u], 32);
2305 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002306
Gilles Peskine449bd832023-01-11 14:50:10 +01002307 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002308
Gilles Peskine449bd832023-01-11 14:50:10 +01002309 if (mode == MBEDTLS_AES_DECRYPT) {
2310 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2311 if (ret != 0) {
2312 goto exit;
2313 }
2314 memcpy(buf, aes_test_xts_ct32[u], len);
2315 aes_tests = aes_test_xts_pt32[u];
2316 } else {
2317 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2318 if (ret != 0) {
2319 goto exit;
2320 }
2321 memcpy(buf, aes_test_xts_pt32[u], len);
2322 aes_tests = aes_test_xts_ct32[u];
2323 }
2324
2325
2326 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2327 buf, buf);
2328 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002329 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002330 }
2331
2332 if (memcmp(buf, aes_tests, len) != 0) {
2333 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002334 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002335 }
2336
2337 if (verbose != 0) {
2338 mbedtls_printf("passed\n");
2339 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002340 }
2341
Gilles Peskine449bd832023-01-11 14:50:10 +01002342 if (verbose != 0) {
2343 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002344 }
2345
Gilles Peskine449bd832023-01-11 14:50:10 +01002346 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002347 }
2348#endif /* MBEDTLS_CIPHER_MODE_XTS */
2349
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002350 ret = 0;
2351
2352exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002353 if (ret != 0 && verbose != 0) {
2354 mbedtls_printf("failed\n");
2355 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002356
Gilles Peskine449bd832023-01-11 14:50:10 +01002357 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002358
Gilles Peskine449bd832023-01-11 14:50:10 +01002359 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002360}
2361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002362#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002364#endif /* MBEDTLS_AES_C */