blob: 3e27cd39bee44fc328d652f3321f43003e8256e7 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010022 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000023 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Jerry Yu72fd0bd2023-08-18 16:31:01 +080037#if defined(MBEDTLS_ARCH_IS_ARM64)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yud6e312d2023-08-18 17:19:51 +080043#if defined(MBEDTLS_ARCH_IS_X64)
Jerry Yu02b15192023-04-23 14:43:19 +080044#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080045#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080046#endif
47#endif
48
Jerry Yud6e312d2023-08-18 17:19:51 +080049#if defined(MBEDTLS_ARCH_IS_X86)
Jerry Yue62ff092023-08-16 14:15:00 +080050#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
51#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080052#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080053
Jerry Yu61fc5ed2023-08-18 17:28:48 +080054#if defined(MBEDTLS_PADLOCK_C)
55#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080056#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
57#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080058#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
59#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
60 "MBEDTLS_PADLOCK_C is set"
61#endif
62#endif
Jerry Yu02b15192023-04-23 14:43:19 +080063#endif
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000066#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000067#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000069#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010070#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080071#if defined(MBEDTLS_AESCE_C)
72#include "aesce.h"
73#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000074
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000075#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020078
Jerry Yu9e628622023-08-17 11:20:09 +080079#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000080static int aes_padlock_ace = -1;
81#endif
82
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000084/*
85 * Forward S-box
86 */
Dave Rodgman450c1ff2023-09-29 15:52:33 +010087#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || \
88 (!defined(MBEDTLS_AES_SETKEY_ENC_ALT) && (!defined(MBEDTLS_AES_USE_HARDWARE_ONLY) || \
89 !defined(MBEDTLS_AES_ROM_TABLES))) || \
90 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
Paul Bakker5121ce52009-01-03 21:22:43 +000091static const unsigned char FSb[256] =
92{
93 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
94 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
95 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
96 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
97 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
98 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
99 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
100 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
101 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
102 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
103 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
104 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
105 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
106 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
107 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
108 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
109 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
110 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
111 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
112 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
113 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
114 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
115 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
116 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
117 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
118 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
119 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
120 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
121 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
122 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
123 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
124 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
125};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100126#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
127 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000128
129/*
130 * Forward tables
131 */
132#define FT \
133\
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
135 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
136 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
137 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
138 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
139 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
140 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
141 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
142 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
143 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
144 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
145 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
146 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
147 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
148 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
149 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
150 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
151 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
152 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
153 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
154 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
155 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
156 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
157 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
158 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
159 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
160 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
161 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
162 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
163 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
164 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
165 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
166 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
167 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
168 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
169 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
170 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
171 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
172 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
173 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
174 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
175 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
176 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
177 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
178 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
179 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
180 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
181 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
182 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
183 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
184 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
185 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
186 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
187 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
188 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
189 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
190 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
191 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
192 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
193 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
194 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
195 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
196 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
197 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 +0000198
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100199#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100200#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000201static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000202#undef V
203
Hanno Beckerad049a92017-06-19 16:31:54 +0100204#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000207static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000208#undef V
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000211static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000212#undef V
213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000215static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000216#undef V
217
Hanno Becker177d3cf2017-06-07 15:52:48 +0100218#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200219
Dave Rodgman1be24632023-06-29 12:01:24 +0100220#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
221
Paul Bakker5121ce52009-01-03 21:22:43 +0000222#undef FT
223
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100224#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000225/*
226 * Reverse S-box
227 */
228static const unsigned char RSb[256] =
229{
230 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
231 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
232 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
233 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
234 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
235 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
236 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
237 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
238 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
239 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
240 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
241 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
242 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
243 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
244 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
245 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
246 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
247 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
248 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
249 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
250 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
251 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
252 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
253 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
254 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
255 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
256 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
257 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
258 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
259 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
260 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
261 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
262};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100263#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000264
265/*
266 * Reverse tables
267 */
268#define RT \
269\
Gilles Peskine449bd832023-01-11 14:50:10 +0100270 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
271 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
272 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
273 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
274 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
275 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
276 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
277 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
278 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
279 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
280 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
281 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
282 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
283 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
284 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
285 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
286 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
287 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
288 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
289 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
290 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
291 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
292 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
293 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
294 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
295 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
296 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
297 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
298 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
299 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
300 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
301 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
302 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
303 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
304 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
305 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
306 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
307 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
308 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
309 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
310 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
311 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
312 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
313 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
314 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
315 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
316 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
317 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
318 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
319 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
320 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
321 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
322 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
323 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
324 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
325 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
326 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
327 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
328 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
329 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
330 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
331 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
332 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
333 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 +0000334
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100335#if !defined(MBEDTLS_AES_DECRYPT_ALT) || \
336 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100337
Gilles Peskine449bd832023-01-11 14:50:10 +0100338#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000339static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000340#undef V
341
Hanno Beckerad049a92017-06-19 16:31:54 +0100342#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000346#undef V
347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000349static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000350#undef V
351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000353static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000354#undef V
355
Hanno Becker177d3cf2017-06-07 15:52:48 +0100356#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200357
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100358#endif \
359 /* !defined(MBEDTLS_AES_DECRYPT_ALT) || (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)) */
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800360
Paul Bakker5121ce52009-01-03 21:22:43 +0000361#undef RT
362
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100363#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000364/*
365 * Round constants
366 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000367static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000368{
369 0x00000001, 0x00000002, 0x00000004, 0x00000008,
370 0x00000010, 0x00000020, 0x00000040, 0x00000080,
371 0x0000001B, 0x00000036
372};
Dave Rodgman34152a42023-06-27 18:31:24 +0100373#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
377/*
378 * Forward S-box & tables
379 */
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100380#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || \
381 (!defined(MBEDTLS_AES_SETKEY_ENC_ALT) && (!defined(MBEDTLS_AES_USE_HARDWARE_ONLY) || \
382 !defined(MBEDTLS_AES_ROM_TABLES))) || \
383 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
Paul Bakker5121ce52009-01-03 21:22:43 +0000384static unsigned char FSb[256];
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100385#endif
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100386#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200387static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100388#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200389static uint32_t FT1[256];
390static uint32_t FT2[256];
391static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100392#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100393#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000394
395/*
396 * Reverse S-box & tables
397 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100398#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000399static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100400#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100401
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100402#if !defined(MBEDTLS_AES_DECRYPT_ALT) || (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && \
403 !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
Paul Bakker5c2364c2012-10-01 14:41:15 +0000404static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100405#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000406static uint32_t RT1[256];
407static uint32_t RT2[256];
408static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100409#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100410#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Dave Rodgman8c753f92023-06-27 18:16:13 +0100412#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000413/*
414 * Round constants
415 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000416static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
418/*
419 * Tables generation code
420 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100421#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
422#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
423#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
425static int aes_init_done = 0;
426
Gilles Peskine449bd832023-01-11 14:50:10 +0100427static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000428{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800429 int i;
430 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800431 uint8_t pow[256];
432 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 /*
435 * compute pow and log tables over GF(2^8)
436 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800439 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800440 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 }
442
443 /*
444 * calculate the round constants
445 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800447 RCON[i] = x;
448 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 }
450
451 /*
452 * generate the forward and reverse S-boxes
453 */
454 FSb[0x00] = 0x63;
455 RSb[0x63] = 0x00;
456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000458 x = pow[255 - log[i]];
459
Yanray Wangfe944ce2023-06-26 18:16:01 +0800460 y = x; y = (y << 1) | (y >> 7);
461 x ^= y; y = (y << 1) | (y >> 7);
462 x ^= y; y = (y << 1) | (y >> 7);
463 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000464 x ^= y ^ 0x63;
465
Yanray Wangfe944ce2023-06-26 18:16:01 +0800466 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000467 RSb[x] = (unsigned char) i;
468 }
469
470 /*
471 * generate the forward and reverse tables
472 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000474 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800475 y = XTIME(x);
476 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 FT0[i] = ((uint32_t) y) ^
479 ((uint32_t) x << 8) ^
480 ((uint32_t) x << 16) ^
481 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Hanno Beckerad049a92017-06-19 16:31:54 +0100483#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 FT1[i] = ROTL8(FT0[i]);
485 FT2[i] = ROTL8(FT1[i]);
486 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100487#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
489 x = RSb[i];
490
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100491#if !defined(MBEDTLS_AES_DECRYPT_ALT) || \
492 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
494 ((uint32_t) MUL(0x09, x) << 8) ^
495 ((uint32_t) MUL(0x0D, x) << 16) ^
496 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000497
Hanno Beckerad049a92017-06-19 16:31:54 +0100498#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 RT1[i] = ROTL8(RT0[i]);
500 RT2[i] = ROTL8(RT1[i]);
501 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100502#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100503#endif \
504 /* !defined(MBEDTLS_AES_DECRYPT_ALT) || (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 }
506}
507
Dave Rodgman8c753f92023-06-27 18:16:13 +0100508#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
509
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200510#undef ROTL8
511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000513
Hanno Beckerad049a92017-06-19 16:31:54 +0100514#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200515
Gilles Peskine449bd832023-01-11 14:50:10 +0100516#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
517#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
518#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200519
520#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100521#define AES_RT1(idx) ROTL8(RT0[idx])
522#define AES_RT2(idx) ROTL16(RT0[idx])
523#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200524
525#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100526#define AES_FT1(idx) ROTL8(FT0[idx])
527#define AES_FT2(idx) ROTL16(FT0[idx])
528#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200529
Hanno Becker177d3cf2017-06-07 15:52:48 +0100530#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200531
532#define AES_RT0(idx) RT0[idx]
533#define AES_RT1(idx) RT1[idx]
534#define AES_RT2(idx) RT2[idx]
535#define AES_RT3(idx) RT3[idx]
536
537#define AES_FT0(idx) FT0[idx]
538#define AES_FT1(idx) FT1[idx]
539#define AES_FT2(idx) FT2[idx]
540#define AES_FT3(idx) FT3[idx]
541
Hanno Becker177d3cf2017-06-07 15:52:48 +0100542#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200543
Gilles Peskine449bd832023-01-11 14:50:10 +0100544void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200545{
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200547}
548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200550{
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200552 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200556}
557
Jaeden Amero9366feb2018-05-29 18:55:17 +0100558#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100559void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100560{
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 mbedtls_aes_init(&ctx->crypt);
562 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100563}
564
Gilles Peskine449bd832023-01-11 14:50:10 +0100565void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100566{
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100568 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 }
Simon Butcher5201e412018-12-06 17:40:14 +0000570
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 mbedtls_aes_free(&ctx->crypt);
572 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100573}
574#endif /* MBEDTLS_CIPHER_MODE_XTS */
575
Gilles Peskine0de8f852023-03-16 17:14:59 +0100576/* Some implementations need the round keys to be aligned.
577 * Return an offset to be added to buf, such that (buf + offset) is
578 * correctly aligned.
579 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
580 * i.e. an offset of 1 means 4 bytes and so on.
581 */
Jerry Yu96084472023-08-17 18:10:45 +0800582#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100583 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100584#define MAY_NEED_TO_ALIGN
585#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100586
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100587#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
588 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100589static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
590{
591#if defined(MAY_NEED_TO_ALIGN)
592 int align_16_bytes = 0;
593
Jerry Yu9e628622023-08-17 11:20:09 +0800594#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100595 if (aes_padlock_ace == -1) {
596 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
597 }
598 if (aes_padlock_ace) {
599 align_16_bytes = 1;
600 }
601#endif
602
Gilles Peskine9c682e72023-03-16 17:21:33 +0100603#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100604 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
605 align_16_bytes = 1;
606 }
607#endif
608
609 if (align_16_bytes) {
610 /* These implementations needs 16-byte alignment
611 * for the round key array. */
612 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
613 if (delta == 0) {
614 return 0;
615 } else {
616 return 4 - delta; // 16 bytes = 4 uint32_t
617 }
618 }
619#else /* MAY_NEED_TO_ALIGN */
620 (void) buf;
621#endif /* MAY_NEED_TO_ALIGN */
622
623 return 0;
624}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100625#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
626 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100627
Paul Bakker5121ce52009-01-03 21:22:43 +0000628/*
629 * AES key schedule (encryption)
630 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200631#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100632int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
633 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000634{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000635 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000636
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000638 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800639#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 case 192: ctx->nr = 12; break;
641 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800642#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000644 }
645
Simon Butcher5201e412018-12-06 17:40:14 +0000646#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000648 aes_gen_tables();
649 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000650 }
651#endif
652
Gilles Peskine0de8f852023-03-16 17:14:59 +0100653 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100654 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000655
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100656#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
658 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
659 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100660#endif
661
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800662#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100663 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800664 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
665 }
666#endif
667
Jerry Yu29c91ba2023-08-04 11:02:04 +0800668#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800669 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000671 }
672
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 case 10:
675
Jerry Yu3a0f0442023-08-17 17:06:21 +0800676 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000677 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
679 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
680 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
681 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
683 RK[5] = RK[1] ^ RK[4];
684 RK[6] = RK[2] ^ RK[5];
685 RK[7] = RK[3] ^ RK[6];
686 }
687 break;
688
Arto Kinnunen732ca322023-04-14 14:26:10 +0800689#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000690 case 12:
691
Jerry Yu3a0f0442023-08-17 17:06:21 +0800692 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000693 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
695 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
696 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
697 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
699 RK[7] = RK[1] ^ RK[6];
700 RK[8] = RK[2] ^ RK[7];
701 RK[9] = RK[3] ^ RK[8];
702 RK[10] = RK[4] ^ RK[9];
703 RK[11] = RK[5] ^ RK[10];
704 }
705 break;
706
707 case 14:
708
Jerry Yu3a0f0442023-08-17 17:06:21 +0800709 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000710 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
712 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
713 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
714 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
716 RK[9] = RK[1] ^ RK[8];
717 RK[10] = RK[2] ^ RK[9];
718 RK[11] = RK[3] ^ RK[10];
719
720 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
722 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
723 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
724 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000725
726 RK[13] = RK[5] ^ RK[12];
727 RK[14] = RK[6] ^ RK[13];
728 RK[15] = RK[7] ^ RK[14];
729 }
730 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800731#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000732 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800735#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000736}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200737#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000738
739/*
740 * AES key schedule (decryption)
741 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200742#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100743int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
744 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000745{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800746#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800747 uint32_t *SK;
748#endif
749 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200750 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000751 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800752
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200753
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000755
Gilles Peskine0de8f852023-03-16 17:14:59 +0100756 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100757 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200759 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200761 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000763
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200764 ctx->nr = cty.nr;
765
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100766#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
768 mbedtls_aesni_inverse_key((unsigned char *) RK,
769 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200770 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100771 }
772#endif
773
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800774#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100775 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800776 mbedtls_aesce_inverse_key(
777 (unsigned char *) RK,
778 (const unsigned char *) (cty.buf + cty.rk_offset),
779 ctx->nr);
780 goto exit;
781 }
782#endif
783
Jerry Yu29c91ba2023-08-04 11:02:04 +0800784#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100785 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000786
787 *RK++ = *SK++;
788 *RK++ = *SK++;
789 *RK++ = *SK++;
790 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800791 SK -= 8;
792 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
793 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
795 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
796 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
797 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000798 }
799 }
800
801 *RK++ = *SK++;
802 *RK++ = *SK++;
803 *RK++ = *SK++;
804 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800805#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200806exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000810}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100811#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100812
813#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100814static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
815 unsigned int keybits,
816 const unsigned char **key1,
817 unsigned int *key1bits,
818 const unsigned char **key2,
819 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100820{
821 const unsigned int half_keybits = keybits / 2;
822 const unsigned int half_keybytes = half_keybits / 8;
823
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100825 case 256: break;
826 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100828 }
829
830 *key1bits = half_keybits;
831 *key2bits = half_keybits;
832 *key1 = &key[0];
833 *key2 = &key[half_keybytes];
834
835 return 0;
836}
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
839 const unsigned char *key,
840 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100841{
Janos Follath24eed8d2019-11-22 13:21:35 +0000842 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100843 const unsigned char *key1, *key2;
844 unsigned int key1bits, key2bits;
845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
847 &key2, &key2bits);
848 if (ret != 0) {
849 return ret;
850 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100851
852 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
854 if (ret != 0) {
855 return ret;
856 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100857
858 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100860}
861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
863 const unsigned char *key,
864 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100865{
Janos Follath24eed8d2019-11-22 13:21:35 +0000866 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100867 const unsigned char *key1, *key2;
868 unsigned int key1bits, key2bits;
869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
871 &key2, &key2bits);
872 if (ret != 0) {
873 return ret;
874 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100875
876 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
878 if (ret != 0) {
879 return ret;
880 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100881
882 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100884}
885#endif /* MBEDTLS_CIPHER_MODE_XTS */
886
Gilles Peskine449bd832023-01-11 14:50:10 +0100887#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100888 do \
889 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
891 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
892 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
893 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100894 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
896 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
897 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
898 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100899 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
901 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
902 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
903 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100904 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
906 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
907 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
908 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
909 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100912 do \
913 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
915 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
916 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
917 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100918 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
920 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
921 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
922 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100923 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
925 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
926 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
927 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100928 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
930 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
931 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
932 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
933 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000934
935/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936 * AES-ECB block encryption
937 */
938#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100939int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
940 const unsigned char input[16],
941 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200942{
943 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100944 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200946 uint32_t X[4];
947 uint32_t Y[4];
948 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
951 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
952 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
953 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
956 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]);
957 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 +0200958 }
959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 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 +0200961
Gilles Peskine5197c662020-08-26 17:03:24 +0200962 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
965 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
966 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Gilles Peskine5197c662020-08-26 17:03:24 +0200968 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
971 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
972 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Gilles Peskine5197c662020-08-26 17:03:24 +0200974 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
977 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
978 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200979
Gilles Peskine5197c662020-08-26 17:03:24 +0200980 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
982 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
983 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
984 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
987 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
988 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
989 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500992
Gilles Peskine449bd832023-01-11 14:50:10 +0100993 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200994}
995#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
996
997/*
998 * AES-ECB block decryption
999 */
1000#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +01001001int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
1002 const unsigned char input[16],
1003 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001004{
1005 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +01001006 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001008 uint32_t X[4];
1009 uint32_t Y[4];
1010 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1013 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1014 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1015 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1018 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]);
1019 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 +02001020 }
1021
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 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 +02001023
Gilles Peskine5197c662020-08-26 17:03:24 +02001024 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1027 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1028 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001029
Gilles Peskine5197c662020-08-26 17:03:24 +02001030 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1033 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1034 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001035
Gilles Peskine5197c662020-08-26 17:03:24 +02001036 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1039 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1040 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001041
Gilles Peskine5197c662020-08-26 17:03:24 +02001042 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1044 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1045 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1046 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1049 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1050 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1051 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001054
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001056}
1057#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1058
Gilles Peskine0de8f852023-03-16 17:14:59 +01001059#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001060/* VIA Padlock and our intrinsics-based implementation of AESNI require
1061 * the round keys to be aligned on a 16-byte boundary. We take care of this
1062 * before creating them, but the AES context may have moved (this can happen
1063 * if the library is called from a language with managed memory), and in later
1064 * calls it might have a different alignment with respect to 16-byte memory.
1065 * So we may need to realign.
1066 */
1067static void aes_maybe_realign(mbedtls_aes_context *ctx)
1068{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001069 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1070 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001071 memmove(ctx->buf + new_offset, // new address
1072 ctx->buf + ctx->rk_offset, // current address
1073 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1074 ctx->rk_offset = new_offset;
1075 }
1076}
1077#endif
1078
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001079/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001080 * AES-ECB block encryption/decryption
1081 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001082int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1083 int mode,
1084 const unsigned char input[16],
1085 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001086{
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001088 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001090
Gilles Peskine0de8f852023-03-16 17:14:59 +01001091#if defined(MAY_NEED_TO_ALIGN)
1092 aes_maybe_realign(ctx);
1093#endif
1094
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001095#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1097 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1098 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001099#endif
1100
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001101#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001102 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001103 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1104 }
1105#endif
1106
Jerry Yu9e628622023-08-17 11:20:09 +08001107#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001109 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001110 }
1111#endif
1112
Jerry Yu29c91ba2023-08-04 11:02:04 +08001113#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 if (mode == MBEDTLS_AES_ENCRYPT) {
1115 return mbedtls_internal_aes_encrypt(ctx, input, output);
1116 } else {
1117 return mbedtls_internal_aes_decrypt(ctx, input, output);
1118 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001119#endif
1120
Paul Bakker5121ce52009-01-03 21:22:43 +00001121}
1122
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001123#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001124
Paul Bakker5121ce52009-01-03 21:22:43 +00001125/*
1126 * AES-CBC buffer encryption/decryption
1127 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001128int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1129 int mode,
1130 size_t length,
1131 unsigned char iv[16],
1132 const unsigned char *input,
1133 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001134{
Gilles Peskine7820a572021-07-07 21:08:28 +02001135 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001136 unsigned char temp[16];
1137
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001139 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001141
Paul Elliott2ad93672023-08-11 11:07:06 +01001142 /* Nothing to do if length is zero. */
1143 if (length == 0) {
1144 return 0;
1145 }
1146
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 if (length % 16) {
1148 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1149 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001150
Jerry Yu9e628622023-08-17 11:20:09 +08001151#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 if (aes_padlock_ace > 0) {
1153 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1154 return 0;
1155 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001156
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001157 // If padlock data misaligned, we just fall back to
1158 // unaccelerated mode
1159 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001160 }
1161#endif
1162
Dave Rodgman906c63c2023-06-14 17:53:51 +01001163 const unsigned char *ivp = iv;
1164
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 if (mode == MBEDTLS_AES_DECRYPT) {
1166 while (length > 0) {
1167 memcpy(temp, input, 16);
1168 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1169 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001170 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001172 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001173 * the result for the next block in CBC, and the cost of transferring that data from
1174 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001175 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001176
Gilles Peskine449bd832023-01-11 14:50:10 +01001177 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001178
1179 input += 16;
1180 output += 16;
1181 length -= 16;
1182 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 } else {
1184 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001185 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001186
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1188 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001189 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001191 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001192
1193 input += 16;
1194 output += 16;
1195 length -= 16;
1196 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001197 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001198 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001199 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001200
Gilles Peskine7820a572021-07-07 21:08:28 +02001201exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001203}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001205
Aorimn5f778012016-06-09 23:22:58 +02001206#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001207
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001208typedef unsigned char mbedtls_be128[16];
1209
1210/*
1211 * GF(2^128) multiplication function
1212 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001213 * This function multiplies a field element by x in the polynomial field
1214 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001215 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001216 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001217 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001218#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001219MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001220#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001221static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001222 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001223{
1224 uint64_t a, b, ra, rb;
1225
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 a = MBEDTLS_GET_UINT64_LE(x, 0);
1227 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001228
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1230 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001231
Gilles Peskine449bd832023-01-11 14:50:10 +01001232 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1233 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001234}
1235
Aorimn5f778012016-06-09 23:22:58 +02001236/*
1237 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001238 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001239 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001240 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001241 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001242#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001243MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001244#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001245int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1246 int mode,
1247 size_t length,
1248 const unsigned char data_unit[16],
1249 const unsigned char *input,
1250 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001251{
Janos Follath24eed8d2019-11-22 13:21:35 +00001252 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253 size_t blocks = length / 16;
1254 size_t leftover = length % 16;
1255 unsigned char tweak[16];
1256 unsigned char prev_tweak[16];
1257 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001258
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001260 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001262
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001263 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001266 }
Aorimn5f778012016-06-09 23:22:58 +02001267
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001268 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001270 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 }
Aorimn5f778012016-06-09 23:22:58 +02001272
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1275 data_unit, tweak);
1276 if (ret != 0) {
1277 return ret;
1278 }
Aorimn5f778012016-06-09 23:22:58 +02001279
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001281 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282 /* We are on the last block in a decrypt operation that has
1283 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001284 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285 * the leftovers and then update the current tweak for use on this,
1286 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 memcpy(prev_tweak, tweak, sizeof(tweak));
1288 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289 }
1290
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001292
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1294 if (ret != 0) {
1295 return ret;
1296 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001297
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001299
1300 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001301 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001302
1303 output += 16;
1304 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001305 }
1306
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001308 /* If we are on the leftover bytes in a decrypt operation, we need to
1309 * use the previous tweak for these bytes (as saved in prev_tweak). */
1310 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001311
Jaeden Amerod82cd862018-04-28 15:02:45 +01001312 /* We are now on the final part of the data unit, which doesn't divide
1313 * evenly by 16. It's time for ciphertext stealing. */
1314 size_t i;
1315 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001316
Jaeden Amerod82cd862018-04-28 15:02:45 +01001317 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001318 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001319 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001320 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001321 }
Aorimn5f778012016-06-09 23:22:58 +02001322
Dave Rodgman069e7f42022-11-24 19:37:26 +00001323 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001325
Jaeden Amerod82cd862018-04-28 15:02:45 +01001326 /* Copy ciphertext bytes from the previous block for input in this
1327 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001329
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1331 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001332 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 }
Aorimn5f778012016-06-09 23:22:58 +02001334
Jaeden Amerod82cd862018-04-28 15:02:45 +01001335 /* Write the result back to the previous block, overriding the previous
1336 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001337 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001338 }
1339
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001341}
1342#endif /* MBEDTLS_CIPHER_MODE_XTS */
1343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001344#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001345/*
1346 * AES-CFB128 buffer encryption/decryption
1347 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001348int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1349 int mode,
1350 size_t length,
1351 size_t *iv_off,
1352 unsigned char iv[16],
1353 const unsigned char *input,
1354 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001355{
Paul Bakker27fdf462011-06-09 13:55:13 +00001356 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001357 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001358 size_t n;
1359
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001361 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001363
1364 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001365
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 if (n > 15) {
1367 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1368 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001369
Gilles Peskine449bd832023-01-11 14:50:10 +01001370 if (mode == MBEDTLS_AES_DECRYPT) {
1371 while (length--) {
1372 if (n == 0) {
1373 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1374 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001375 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001377 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001378
1379 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001381 iv[n] = (unsigned char) c;
1382
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001384 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 } else {
1386 while (length--) {
1387 if (n == 0) {
1388 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1389 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001390 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001392 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001393
Gilles Peskine449bd832023-01-11 14:50:10 +01001394 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001395
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001397 }
1398 }
1399
1400 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001401 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001402
Gilles Peskine7820a572021-07-07 21:08:28 +02001403exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001404 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001405}
Paul Bakker556efba2014-01-24 15:38:12 +01001406
1407/*
1408 * AES-CFB8 buffer encryption/decryption
1409 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001410int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1411 int mode,
1412 size_t length,
1413 unsigned char iv[16],
1414 const unsigned char *input,
1415 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001416{
Gilles Peskine7820a572021-07-07 21:08:28 +02001417 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001418 unsigned char c;
1419 unsigned char ov[17];
1420
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001422 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 }
1424 while (length--) {
1425 memcpy(ov, iv, 16);
1426 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1427 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001428 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 }
Paul Bakker556efba2014-01-24 15:38:12 +01001430
Gilles Peskine449bd832023-01-11 14:50:10 +01001431 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001432 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 }
Paul Bakker556efba2014-01-24 15:38:12 +01001434
Gilles Peskine449bd832023-01-11 14:50:10 +01001435 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001436
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001438 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001439 }
Paul Bakker556efba2014-01-24 15:38:12 +01001440
Gilles Peskine449bd832023-01-11 14:50:10 +01001441 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001442 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001443 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001444
Gilles Peskine7820a572021-07-07 21:08:28 +02001445exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001446 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001447}
Simon Butcher76a5b222018-04-22 22:57:27 +01001448#endif /* MBEDTLS_CIPHER_MODE_CFB */
1449
1450#if defined(MBEDTLS_CIPHER_MODE_OFB)
1451/*
1452 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1453 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001454int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1455 size_t length,
1456 size_t *iv_off,
1457 unsigned char iv[16],
1458 const unsigned char *input,
1459 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001460{
Simon Butcherad4e4932018-04-29 00:43:47 +01001461 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001462 size_t n;
1463
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001464 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001465
Gilles Peskine449bd832023-01-11 14:50:10 +01001466 if (n > 15) {
1467 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1468 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001469
Gilles Peskine449bd832023-01-11 14:50:10 +01001470 while (length--) {
1471 if (n == 0) {
1472 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1473 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001474 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001475 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001476 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001477 *output++ = *input++ ^ iv[n];
1478
Gilles Peskine449bd832023-01-11 14:50:10 +01001479 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001480 }
1481
1482 *iv_off = n;
1483
Simon Butcherad4e4932018-04-29 00:43:47 +01001484exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001485 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001486}
1487#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001490/*
1491 * AES-CTR buffer encryption/decryption
1492 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001493int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1494 size_t length,
1495 size_t *nc_off,
1496 unsigned char nonce_counter[16],
1497 unsigned char stream_block[16],
1498 const unsigned char *input,
1499 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001500{
Paul Bakker369e14b2012-04-18 14:16:09 +00001501 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001502 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001503 size_t n;
1504
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001505 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001506
Gilles Peskine449bd832023-01-11 14:50:10 +01001507 if (n > 0x0F) {
1508 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1509 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001510
Gilles Peskine449bd832023-01-11 14:50:10 +01001511 while (length--) {
1512 if (n == 0) {
1513 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1514 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001515 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001516 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001517
Gilles Peskine449bd832023-01-11 14:50:10 +01001518 for (i = 16; i > 0; i--) {
1519 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001520 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001521 }
1522 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001523 }
1524 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001525 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001526
Gilles Peskine449bd832023-01-11 14:50:10 +01001527 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001528 }
1529
1530 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001531 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001532
Gilles Peskine7820a572021-07-07 21:08:28 +02001533exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001534 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001535}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001536#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001537
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001541/*
1542 * AES test vectors from:
1543 *
1544 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1545 */
Yanray Wang62c99912023-05-11 11:06:53 +08001546static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001547{
1548 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1549 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001550#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001551 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1552 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1553 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1554 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001555#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001556};
1557
Yanray Wang62c99912023-05-11 11:06:53 +08001558static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001559{
1560 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1561 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001562#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001563 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1564 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1565 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1566 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001567#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001568};
1569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001571static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001572{
1573 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1574 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001575#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001576 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1577 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1578 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1579 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001580#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001581};
1582
Yanray Wang62c99912023-05-11 11:06:53 +08001583static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001584{
1585 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1586 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001587#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001588 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1589 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1590 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1591 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001592#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001593};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001594#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001595
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001596#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001597/*
1598 * AES-CFB128 test vectors from:
1599 *
1600 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1601 */
Yanray Wang62c99912023-05-11 11:06:53 +08001602static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001603{
1604 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1605 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001606#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001607 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1608 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1609 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1610 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1611 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1612 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1613 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001614#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001615};
1616
1617static const unsigned char aes_test_cfb128_iv[16] =
1618{
1619 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1620 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1621};
1622
1623static const unsigned char aes_test_cfb128_pt[64] =
1624{
1625 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1626 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1627 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1628 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1629 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1630 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1631 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1632 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1633};
1634
Yanray Wang62c99912023-05-11 11:06:53 +08001635static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001636{
1637 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1638 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1639 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1640 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1641 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1642 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1643 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1644 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001645#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001646 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1647 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1648 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1649 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1650 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1651 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1652 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1653 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1654 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1655 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1656 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1657 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1658 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1659 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1660 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1661 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001662#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001663};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001664#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001665
Simon Butcherad4e4932018-04-29 00:43:47 +01001666#if defined(MBEDTLS_CIPHER_MODE_OFB)
1667/*
1668 * AES-OFB test vectors from:
1669 *
Simon Butcher5db13622018-06-04 22:11:25 +01001670 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001671 */
Yanray Wang62c99912023-05-11 11:06:53 +08001672static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001673{
1674 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1675 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001676#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001677 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1678 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1679 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1680 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1681 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1682 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1683 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001684#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001685};
1686
1687static const unsigned char aes_test_ofb_iv[16] =
1688{
1689 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1690 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1691};
1692
1693static const unsigned char aes_test_ofb_pt[64] =
1694{
1695 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1696 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1697 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1698 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1699 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1700 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1701 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1702 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1703};
1704
Yanray Wang62c99912023-05-11 11:06:53 +08001705static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001706{
1707 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1708 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1709 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1710 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1711 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1712 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1713 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1714 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001715#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001716 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1717 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1718 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1719 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1720 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1721 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1722 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1723 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1724 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1725 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1726 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1727 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1728 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1729 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1730 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1731 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001732#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001733};
1734#endif /* MBEDTLS_CIPHER_MODE_OFB */
1735
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001736#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001737/*
1738 * AES-CTR test vectors from:
1739 *
1740 * http://www.faqs.org/rfcs/rfc3686.html
1741 */
1742
Yanray Wang62c99912023-05-11 11:06:53 +08001743static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001744{
1745 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1746 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1747 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1748 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1749 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1750 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1751};
1752
Yanray Wang62c99912023-05-11 11:06:53 +08001753static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001754{
1755 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1757 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1758 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1759 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1760 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1761};
1762
Yanray Wang62c99912023-05-11 11:06:53 +08001763static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001764{
1765 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1766 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001767 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1768 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1769 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1770 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1771
1772 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1773 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1774 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1775 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1776 0x20, 0x21, 0x22, 0x23 }
1777};
1778
Yanray Wang62c99912023-05-11 11:06:53 +08001779static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001780{
1781 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1782 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1783 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1784 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1785 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1786 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1787 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1788 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1789 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1790 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1791 0x25, 0xB2, 0x07, 0x2F }
1792};
1793
1794static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001795{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001796#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001797
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001798#if defined(MBEDTLS_CIPHER_MODE_XTS)
1799/*
1800 * AES-XTS test vectors from:
1801 *
1802 * IEEE P1619/D16 Annex B
1803 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1804 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1805 */
1806static const unsigned char aes_test_xts_key[][32] =
1807{
1808 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1812 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1813 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1814 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1815 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1816 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1817 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1818 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1819 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1820};
1821
1822static const unsigned char aes_test_xts_pt32[][32] =
1823{
1824 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1825 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1828 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1829 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1830 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1831 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1832 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1833 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1834 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1835 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1836};
1837
1838static const unsigned char aes_test_xts_ct32[][32] =
1839{
1840 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1841 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1842 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1843 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1844 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1845 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1846 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1847 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1848 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1849 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1850 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1851 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1852};
1853
1854static const unsigned char aes_test_xts_data_unit[][16] =
1855{
Gilles Peskine449bd832023-01-11 14:50:10 +01001856 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1858 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1860 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001862};
1863
1864#endif /* MBEDTLS_CIPHER_MODE_XTS */
1865
Paul Bakker5121ce52009-01-03 21:22:43 +00001866/*
1867 * Checkup routine
1868 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001869int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001870{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001871 int ret = 0, i, j, u, mode;
1872 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001873 unsigned char key[32];
1874 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001875 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001876#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1877 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001879#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001881 unsigned char prv[16];
1882#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001883#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1884 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001885 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001886#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001887#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001888 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001889#endif
1890#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001891 unsigned char nonce_counter[16];
1892 unsigned char stream_block[16];
1893#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001894 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001895
Gilles Peskine449bd832023-01-11 14:50:10 +01001896 memset(key, 0, 32);
1897 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001898
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001899 if (verbose != 0) {
1900#if defined(MBEDTLS_AES_ALT)
1901 mbedtls_printf(" AES note: alternative implementation.\n");
1902#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001903#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001904#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001905 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001906#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001907 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001908#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001909#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001910#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001911 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1912 mbedtls_printf(" AES note: using AESNI.\n");
1913 } else
1914#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001915#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001916 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1917 mbedtls_printf(" AES note: using VIA Padlock.\n");
1918 } else
1919#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001920#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001921 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001922 mbedtls_printf(" AES note: using AESCE.\n");
1923 } else
1924#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001925 {
1926#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1927 mbedtls_printf(" AES note: built-in implementation.\n");
1928#endif
1929 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001930#endif /* MBEDTLS_AES_ALT */
1931 }
1932
Paul Bakker5121ce52009-01-03 21:22:43 +00001933 /*
1934 * ECB mode
1935 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001936 {
1937 static const int num_tests =
1938 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001939
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001940 for (i = 0; i < num_tests << 1; i++) {
1941 u = i >> 1;
1942 keybits = 128 + u * 64;
1943 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001944
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001945 if (verbose != 0) {
1946 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1947 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1948 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001949
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001950 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001951
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001952 if (mode == MBEDTLS_AES_DECRYPT) {
1953 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1954 aes_tests = aes_test_ecb_dec[u];
1955 } else {
1956 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1957 aes_tests = aes_test_ecb_enc[u];
1958 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001959
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001960 /*
1961 * AES-192 is an optional feature that may be unavailable when
1962 * there is an alternative underlying implementation i.e. when
1963 * MBEDTLS_AES_ALT is defined.
1964 */
1965 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1966 mbedtls_printf("skipped\n");
1967 continue;
1968 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001969 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001970 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001971
1972 for (j = 0; j < 10000; j++) {
1973 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1974 if (ret != 0) {
1975 goto exit;
1976 }
1977 }
1978
1979 if (memcmp(buf, aes_tests, 16) != 0) {
1980 ret = 1;
1981 goto exit;
1982 }
1983
1984 if (verbose != 0) {
1985 mbedtls_printf("passed\n");
1986 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001987 }
1988
Gilles Peskine449bd832023-01-11 14:50:10 +01001989 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001990 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001991 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001992 }
1993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001994#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001995 /*
1996 * CBC mode
1997 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001998 {
1999 static const int num_tests =
2000 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00002001
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002002 for (i = 0; i < num_tests << 1; i++) {
2003 u = i >> 1;
2004 keybits = 128 + u * 64;
2005 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01002006
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002007 if (verbose != 0) {
2008 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2009 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002010 }
2011
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002012 memset(iv, 0, 16);
2013 memset(prv, 0, 16);
2014 memset(buf, 0, 16);
2015
2016 if (mode == MBEDTLS_AES_DECRYPT) {
2017 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2018 aes_tests = aes_test_cbc_dec[u];
2019 } else {
2020 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2021 aes_tests = aes_test_cbc_enc[u];
2022 }
2023
2024 /*
2025 * AES-192 is an optional feature that may be unavailable when
2026 * there is an alternative underlying implementation i.e. when
2027 * MBEDTLS_AES_ALT is defined.
2028 */
2029 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2030 mbedtls_printf("skipped\n");
2031 continue;
2032 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002033 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002034 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002035
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002036 for (j = 0; j < 10000; j++) {
2037 if (mode == MBEDTLS_AES_ENCRYPT) {
2038 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002039
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002040 memcpy(tmp, prv, 16);
2041 memcpy(prv, buf, 16);
2042 memcpy(buf, tmp, 16);
2043 }
2044
2045 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2046 if (ret != 0) {
2047 goto exit;
2048 }
2049
2050 }
2051
2052 if (memcmp(buf, aes_tests, 16) != 0) {
2053 ret = 1;
2054 goto exit;
2055 }
2056
2057 if (verbose != 0) {
2058 mbedtls_printf("passed\n");
2059 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002060 }
2061
Gilles Peskine449bd832023-01-11 14:50:10 +01002062 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002063 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002064 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002065 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002066#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002068#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002069 /*
2070 * CFB128 mode
2071 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002072 {
2073 static const int num_tests =
2074 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002075
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002076 for (i = 0; i < num_tests << 1; i++) {
2077 u = i >> 1;
2078 keybits = 128 + u * 64;
2079 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002080
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002081 if (verbose != 0) {
2082 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2083 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2084 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002085
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002086 memcpy(iv, aes_test_cfb128_iv, 16);
2087 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002089 offset = 0;
2090 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2091 /*
2092 * AES-192 is an optional feature that may be unavailable when
2093 * there is an alternative underlying implementation i.e. when
2094 * MBEDTLS_AES_ALT is defined.
2095 */
2096 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2097 mbedtls_printf("skipped\n");
2098 continue;
2099 } else if (ret != 0) {
2100 goto exit;
2101 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002102
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002103 if (mode == MBEDTLS_AES_DECRYPT) {
2104 memcpy(buf, aes_test_cfb128_ct[u], 64);
2105 aes_tests = aes_test_cfb128_pt;
2106 } else {
2107 memcpy(buf, aes_test_cfb128_pt, 64);
2108 aes_tests = aes_test_cfb128_ct[u];
2109 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002110
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002111 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2112 if (ret != 0) {
2113 goto exit;
2114 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002115
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002116 if (memcmp(buf, aes_tests, 64) != 0) {
2117 ret = 1;
2118 goto exit;
2119 }
2120
2121 if (verbose != 0) {
2122 mbedtls_printf("passed\n");
2123 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002124 }
2125
Gilles Peskine449bd832023-01-11 14:50:10 +01002126 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002127 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002128 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002129 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002130#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002131
Simon Butcherad4e4932018-04-29 00:43:47 +01002132#if defined(MBEDTLS_CIPHER_MODE_OFB)
2133 /*
2134 * OFB mode
2135 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002136 {
2137 static const int num_tests =
2138 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002139
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002140 for (i = 0; i < num_tests << 1; i++) {
2141 u = i >> 1;
2142 keybits = 128 + u * 64;
2143 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002144
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002145 if (verbose != 0) {
2146 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2147 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2148 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002149
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002150 memcpy(iv, aes_test_ofb_iv, 16);
2151 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002152
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002153 offset = 0;
2154 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2155 /*
2156 * AES-192 is an optional feature that may be unavailable when
2157 * there is an alternative underlying implementation i.e. when
2158 * MBEDTLS_AES_ALT is defined.
2159 */
2160 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2161 mbedtls_printf("skipped\n");
2162 continue;
2163 } else if (ret != 0) {
2164 goto exit;
2165 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002166
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002167 if (mode == MBEDTLS_AES_DECRYPT) {
2168 memcpy(buf, aes_test_ofb_ct[u], 64);
2169 aes_tests = aes_test_ofb_pt;
2170 } else {
2171 memcpy(buf, aes_test_ofb_pt, 64);
2172 aes_tests = aes_test_ofb_ct[u];
2173 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002174
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002175 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2176 if (ret != 0) {
2177 goto exit;
2178 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002179
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002180 if (memcmp(buf, aes_tests, 64) != 0) {
2181 ret = 1;
2182 goto exit;
2183 }
2184
2185 if (verbose != 0) {
2186 mbedtls_printf("passed\n");
2187 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002188 }
2189
Gilles Peskine449bd832023-01-11 14:50:10 +01002190 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002191 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002192 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002193 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002194#endif /* MBEDTLS_CIPHER_MODE_OFB */
2195
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002196#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002197 /*
2198 * CTR mode
2199 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002200 {
2201 static const int num_tests =
2202 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002203
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002204 for (i = 0; i < num_tests << 1; i++) {
2205 u = i >> 1;
2206 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002207
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002208 if (verbose != 0) {
2209 mbedtls_printf(" AES-CTR-128 (%s): ",
2210 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2211 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002212
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002213 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2214 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002215
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002216 offset = 0;
2217 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2218 goto exit;
2219 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002220
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002221 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002222
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002223 if (mode == MBEDTLS_AES_DECRYPT) {
2224 memcpy(buf, aes_test_ctr_ct[u], len);
2225 aes_tests = aes_test_ctr_pt[u];
2226 } else {
2227 memcpy(buf, aes_test_ctr_pt[u], len);
2228 aes_tests = aes_test_ctr_ct[u];
2229 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002230
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002231 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2232 stream_block, buf, buf);
2233 if (ret != 0) {
2234 goto exit;
2235 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002236
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002237 if (memcmp(buf, aes_tests, len) != 0) {
2238 ret = 1;
2239 goto exit;
2240 }
2241
2242 if (verbose != 0) {
2243 mbedtls_printf("passed\n");
2244 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002245 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002246 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002247
Gilles Peskine449bd832023-01-11 14:50:10 +01002248 if (verbose != 0) {
2249 mbedtls_printf("\n");
2250 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002252
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002253#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002254 /*
2255 * XTS mode
2256 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002257 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002258 static const int num_tests =
2259 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2260 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002261
Gilles Peskine449bd832023-01-11 14:50:10 +01002262 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002263
Gilles Peskine449bd832023-01-11 14:50:10 +01002264 for (i = 0; i < num_tests << 1; i++) {
2265 const unsigned char *data_unit;
2266 u = i >> 1;
2267 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002268
Gilles Peskine449bd832023-01-11 14:50:10 +01002269 if (verbose != 0) {
2270 mbedtls_printf(" AES-XTS-128 (%s): ",
2271 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2272 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002273
Gilles Peskine449bd832023-01-11 14:50:10 +01002274 memset(key, 0, sizeof(key));
2275 memcpy(key, aes_test_xts_key[u], 32);
2276 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002277
Gilles Peskine449bd832023-01-11 14:50:10 +01002278 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002279
Gilles Peskine449bd832023-01-11 14:50:10 +01002280 if (mode == MBEDTLS_AES_DECRYPT) {
2281 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2282 if (ret != 0) {
2283 goto exit;
2284 }
2285 memcpy(buf, aes_test_xts_ct32[u], len);
2286 aes_tests = aes_test_xts_pt32[u];
2287 } else {
2288 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2289 if (ret != 0) {
2290 goto exit;
2291 }
2292 memcpy(buf, aes_test_xts_pt32[u], len);
2293 aes_tests = aes_test_xts_ct32[u];
2294 }
2295
2296
2297 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2298 buf, buf);
2299 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002300 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002301 }
2302
2303 if (memcmp(buf, aes_tests, len) != 0) {
2304 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002305 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002306 }
2307
2308 if (verbose != 0) {
2309 mbedtls_printf("passed\n");
2310 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002311 }
2312
Gilles Peskine449bd832023-01-11 14:50:10 +01002313 if (verbose != 0) {
2314 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002315 }
2316
Gilles Peskine449bd832023-01-11 14:50:10 +01002317 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002318 }
2319#endif /* MBEDTLS_CIPHER_MODE_XTS */
2320
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002321 ret = 0;
2322
2323exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002324 if (ret != 0 && verbose != 0) {
2325 mbedtls_printf("failed\n");
2326 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002327
Gilles Peskine449bd832023-01-11 14:50:10 +01002328 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002329
Gilles Peskine449bd832023-01-11 14:50:10 +01002330 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002331}
2332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002333#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002335#endif /* MBEDTLS_AES_C */