blob: 0a7b26ce90445772da40bbe9160b5369990189e1 [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 Rodgman2fd8c2c2023-06-27 21:03:31 +010087#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
88 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000089static const unsigned char FSb[256] =
90{
91 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
92 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
93 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
94 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
95 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
96 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
97 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
98 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
99 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
100 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
101 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
102 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
103 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
104 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
105 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
106 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
107 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
108 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
109 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
110 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
111 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
112 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
113 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
114 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
115 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
116 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
117 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
118 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
119 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
120 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
121 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
122 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
123};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100124#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
125 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000126
127/*
128 * Forward tables
129 */
130#define FT \
131\
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
133 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
134 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
135 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
136 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
137 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
138 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
139 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
140 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
141 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
142 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
143 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
144 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
145 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
146 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
147 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
148 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
149 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
150 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
151 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
152 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
153 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
154 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
155 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
156 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
157 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
158 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
159 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
160 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
161 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
162 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
163 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
164 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
165 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
166 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
167 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
168 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
169 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
170 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
171 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
172 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
173 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
174 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
175 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
176 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
177 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
178 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
179 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
180 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
181 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
182 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
183 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
184 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
185 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
186 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
187 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
188 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
189 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
190 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
191 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
192 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
193 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
194 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
195 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 +0000196
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100197#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100198#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000199static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000200#undef V
201
Hanno Beckerad049a92017-06-19 16:31:54 +0100202#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000205static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000206#undef V
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000209static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000210#undef V
211
Gilles Peskine449bd832023-01-11 14:50:10 +0100212#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000214#undef V
215
Hanno Becker177d3cf2017-06-07 15:52:48 +0100216#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200217
Dave Rodgman1be24632023-06-29 12:01:24 +0100218#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
219
Paul Bakker5121ce52009-01-03 21:22:43 +0000220#undef FT
221
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100222#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000223/*
224 * Reverse S-box
225 */
226static const unsigned char RSb[256] =
227{
228 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
229 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
230 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
231 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
232 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
233 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
234 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
235 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
236 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
237 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
238 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
239 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
240 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
241 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
242 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
243 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
244 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
245 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
246 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
247 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
248 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
249 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
250 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
251 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
252 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
253 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
254 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
255 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
256 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
257 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
258 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
259 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
260};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100261#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
263/*
264 * Reverse tables
265 */
266#define RT \
267\
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
269 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
270 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
271 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
272 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
273 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
274 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
275 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
276 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
277 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
278 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
279 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
280 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
281 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
282 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
283 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
284 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
285 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
286 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
287 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
288 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
289 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
290 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
291 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
292 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
293 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
294 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
295 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
296 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
297 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
298 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
299 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
300 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
301 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
302 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
303 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
304 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
305 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
306 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
307 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
308 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
309 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
310 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
311 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
312 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
313 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
314 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
315 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
316 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
317 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
318 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
319 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
320 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
321 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
322 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
323 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
324 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
325 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
326 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
327 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
328 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
329 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
330 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
331 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 +0000332
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100333#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000336static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000337#undef V
338
Hanno Beckerad049a92017-06-19 16:31:54 +0100339#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000342static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000343#undef V
344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000347#undef V
348
Gilles Peskine449bd832023-01-11 14:50:10 +0100349#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000350static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000351#undef V
352
Hanno Becker177d3cf2017-06-07 15:52:48 +0100353#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200354
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800355#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
356
Paul Bakker5121ce52009-01-03 21:22:43 +0000357#undef RT
358
Dave Rodgman34152a42023-06-27 18:31:24 +0100359#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000360/*
361 * Round constants
362 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000363static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000364{
365 0x00000001, 0x00000002, 0x00000004, 0x00000008,
366 0x00000010, 0x00000020, 0x00000040, 0x00000080,
367 0x0000001B, 0x00000036
368};
Dave Rodgman34152a42023-06-27 18:31:24 +0100369#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000372
373/*
374 * Forward S-box & tables
375 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100376#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
377 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000378static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100379#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
380 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100381#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200382static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100383#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200384static uint32_t FT1[256];
385static uint32_t FT2[256];
386static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100387#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100388#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
390/*
391 * Reverse S-box & tables
392 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100393#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000394static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100395#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100396
397#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000398static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100399#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000400static uint32_t RT1[256];
401static uint32_t RT2[256];
402static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100403#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100404#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Dave Rodgman8c753f92023-06-27 18:16:13 +0100406#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000407/*
408 * Round constants
409 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000410static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412/*
413 * Tables generation code
414 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100415#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
416#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
417#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
419static int aes_init_done = 0;
420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000422{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800423 int i;
424 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800425 uint8_t pow[256];
426 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
428 /*
429 * compute pow and log tables over GF(2^8)
430 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800433 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800434 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000435 }
436
437 /*
438 * calculate the round constants
439 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800441 RCON[i] = x;
442 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000443 }
444
445 /*
446 * generate the forward and reverse S-boxes
447 */
448 FSb[0x00] = 0x63;
449 RSb[0x63] = 0x00;
450
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 x = pow[255 - log[i]];
453
Yanray Wangfe944ce2023-06-26 18:16:01 +0800454 y = x; y = (y << 1) | (y >> 7);
455 x ^= y; y = (y << 1) | (y >> 7);
456 x ^= y; y = (y << 1) | (y >> 7);
457 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000458 x ^= y ^ 0x63;
459
Yanray Wangfe944ce2023-06-26 18:16:01 +0800460 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000461 RSb[x] = (unsigned char) i;
462 }
463
464 /*
465 * generate the forward and reverse tables
466 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800469 y = XTIME(x);
470 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 FT0[i] = ((uint32_t) y) ^
473 ((uint32_t) x << 8) ^
474 ((uint32_t) x << 16) ^
475 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
Hanno Beckerad049a92017-06-19 16:31:54 +0100477#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 FT1[i] = ROTL8(FT0[i]);
479 FT2[i] = ROTL8(FT1[i]);
480 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100481#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
483 x = RSb[i];
484
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100485#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
487 ((uint32_t) MUL(0x09, x) << 8) ^
488 ((uint32_t) MUL(0x0D, x) << 16) ^
489 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
Hanno Beckerad049a92017-06-19 16:31:54 +0100491#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 RT1[i] = ROTL8(RT0[i]);
493 RT2[i] = ROTL8(RT1[i]);
494 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100495#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100496#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000497 }
498}
499
Dave Rodgman8c753f92023-06-27 18:16:13 +0100500#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
501
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200502#undef ROTL8
503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000505
Hanno Beckerad049a92017-06-19 16:31:54 +0100506#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200507
Gilles Peskine449bd832023-01-11 14:50:10 +0100508#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
509#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
510#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200511
512#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100513#define AES_RT1(idx) ROTL8(RT0[idx])
514#define AES_RT2(idx) ROTL16(RT0[idx])
515#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200516
517#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100518#define AES_FT1(idx) ROTL8(FT0[idx])
519#define AES_FT2(idx) ROTL16(FT0[idx])
520#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200521
Hanno Becker177d3cf2017-06-07 15:52:48 +0100522#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200523
524#define AES_RT0(idx) RT0[idx]
525#define AES_RT1(idx) RT1[idx]
526#define AES_RT2(idx) RT2[idx]
527#define AES_RT3(idx) RT3[idx]
528
529#define AES_FT0(idx) FT0[idx]
530#define AES_FT1(idx) FT1[idx]
531#define AES_FT2(idx) FT2[idx]
532#define AES_FT3(idx) FT3[idx]
533
Hanno Becker177d3cf2017-06-07 15:52:48 +0100534#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200537{
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200539}
540
Gilles Peskine449bd832023-01-11 14:50:10 +0100541void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200542{
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200544 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200548}
549
Jaeden Amero9366feb2018-05-29 18:55:17 +0100550#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100551void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100552{
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 mbedtls_aes_init(&ctx->crypt);
554 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100555}
556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100558{
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100560 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 }
Simon Butcher5201e412018-12-06 17:40:14 +0000562
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 mbedtls_aes_free(&ctx->crypt);
564 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100565}
566#endif /* MBEDTLS_CIPHER_MODE_XTS */
567
Gilles Peskine0de8f852023-03-16 17:14:59 +0100568/* Some implementations need the round keys to be aligned.
569 * Return an offset to be added to buf, such that (buf + offset) is
570 * correctly aligned.
571 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
572 * i.e. an offset of 1 means 4 bytes and so on.
573 */
Jerry Yu96084472023-08-17 18:10:45 +0800574#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100575 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100576#define MAY_NEED_TO_ALIGN
577#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100578
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100579#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
580 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100581static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
582{
583#if defined(MAY_NEED_TO_ALIGN)
584 int align_16_bytes = 0;
585
Jerry Yu9e628622023-08-17 11:20:09 +0800586#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100587 if (aes_padlock_ace == -1) {
588 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
589 }
590 if (aes_padlock_ace) {
591 align_16_bytes = 1;
592 }
593#endif
594
Gilles Peskine9c682e72023-03-16 17:21:33 +0100595#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100596 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
597 align_16_bytes = 1;
598 }
599#endif
600
601 if (align_16_bytes) {
602 /* These implementations needs 16-byte alignment
603 * for the round key array. */
604 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
605 if (delta == 0) {
606 return 0;
607 } else {
608 return 4 - delta; // 16 bytes = 4 uint32_t
609 }
610 }
611#else /* MAY_NEED_TO_ALIGN */
612 (void) buf;
613#endif /* MAY_NEED_TO_ALIGN */
614
615 return 0;
616}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100617#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
618 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100619
Paul Bakker5121ce52009-01-03 21:22:43 +0000620/*
621 * AES key schedule (encryption)
622 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200623#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100624int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
625 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000626{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000627 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000628
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800631#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 case 192: ctx->nr = 12; break;
633 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800634#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 }
637
Simon Butcher5201e412018-12-06 17:40:14 +0000638#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000640 aes_gen_tables();
641 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000642 }
643#endif
644
Gilles Peskine0de8f852023-03-16 17:14:59 +0100645 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100646 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000647
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100648#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
650 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
651 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100652#endif
653
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800654#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100655 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800656 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
657 }
658#endif
659
Jerry Yu29c91ba2023-08-04 11:02:04 +0800660#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800661 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 }
664
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 case 10:
667
Jerry Yu3a0f0442023-08-17 17:06:21 +0800668 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000669 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
671 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
672 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
673 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675 RK[5] = RK[1] ^ RK[4];
676 RK[6] = RK[2] ^ RK[5];
677 RK[7] = RK[3] ^ RK[6];
678 }
679 break;
680
Arto Kinnunen732ca322023-04-14 14:26:10 +0800681#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000682 case 12:
683
Jerry Yu3a0f0442023-08-17 17:06:21 +0800684 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000685 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
687 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
688 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
689 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000690
691 RK[7] = RK[1] ^ RK[6];
692 RK[8] = RK[2] ^ RK[7];
693 RK[9] = RK[3] ^ RK[8];
694 RK[10] = RK[4] ^ RK[9];
695 RK[11] = RK[5] ^ RK[10];
696 }
697 break;
698
699 case 14:
700
Jerry Yu3a0f0442023-08-17 17:06:21 +0800701 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000702 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
704 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
705 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
706 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000707
708 RK[9] = RK[1] ^ RK[8];
709 RK[10] = RK[2] ^ RK[9];
710 RK[11] = RK[3] ^ RK[10];
711
712 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
714 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
715 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
716 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
718 RK[13] = RK[5] ^ RK[12];
719 RK[14] = RK[6] ^ RK[13];
720 RK[15] = RK[7] ^ RK[14];
721 }
722 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800723#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000724 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000725
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800727#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000728}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200729#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
731/*
732 * AES key schedule (decryption)
733 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200734#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100735int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
736 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000737{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800738#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800739 uint32_t *SK;
740#endif
741 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000743 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800744
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000747
Gilles Peskine0de8f852023-03-16 17:14:59 +0100748 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100749 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000750
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200751 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200753 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000755
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200756 ctx->nr = cty.nr;
757
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100758#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
760 mbedtls_aesni_inverse_key((unsigned char *) RK,
761 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200762 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100763 }
764#endif
765
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800766#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100767 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800768 mbedtls_aesce_inverse_key(
769 (unsigned char *) RK,
770 (const unsigned char *) (cty.buf + cty.rk_offset),
771 ctx->nr);
772 goto exit;
773 }
774#endif
775
Jerry Yu29c91ba2023-08-04 11:02:04 +0800776#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100777 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000778
779 *RK++ = *SK++;
780 *RK++ = *SK++;
781 *RK++ = *SK++;
782 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800783 SK -= 8;
784 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
785 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
787 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
788 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
789 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 }
791 }
792
793 *RK++ = *SK++;
794 *RK++ = *SK++;
795 *RK++ = *SK++;
796 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800797#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200798exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000800
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000802}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100803#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100804
805#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100806static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
807 unsigned int keybits,
808 const unsigned char **key1,
809 unsigned int *key1bits,
810 const unsigned char **key2,
811 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100812{
813 const unsigned int half_keybits = keybits / 2;
814 const unsigned int half_keybytes = half_keybits / 8;
815
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100817 case 256: break;
818 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100820 }
821
822 *key1bits = half_keybits;
823 *key2bits = half_keybits;
824 *key1 = &key[0];
825 *key2 = &key[half_keybytes];
826
827 return 0;
828}
829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
831 const unsigned char *key,
832 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100833{
Janos Follath24eed8d2019-11-22 13:21:35 +0000834 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100835 const unsigned char *key1, *key2;
836 unsigned int key1bits, key2bits;
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
839 &key2, &key2bits);
840 if (ret != 0) {
841 return ret;
842 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100843
844 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
846 if (ret != 0) {
847 return ret;
848 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100849
850 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100852}
853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
855 const unsigned char *key,
856 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100857{
Janos Follath24eed8d2019-11-22 13:21:35 +0000858 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100859 const unsigned char *key1, *key2;
860 unsigned int key1bits, key2bits;
861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
863 &key2, &key2bits);
864 if (ret != 0) {
865 return ret;
866 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100867
868 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
870 if (ret != 0) {
871 return ret;
872 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100873
874 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100876}
877#endif /* MBEDTLS_CIPHER_MODE_XTS */
878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100880 do \
881 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
883 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
884 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
885 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100886 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
888 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
889 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
890 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100891 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
893 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
894 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
895 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100896 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
898 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
899 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
900 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
901 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100904 do \
905 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
907 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
908 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
909 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100910 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
912 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
913 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
914 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100915 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
917 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
918 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
919 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100920 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
922 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
923 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
924 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
925 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
927/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200928 * AES-ECB block encryption
929 */
930#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100931int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
932 const unsigned char input[16],
933 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934{
935 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100936 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200938 uint32_t X[4];
939 uint32_t Y[4];
940 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
943 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
944 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
945 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
948 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]);
949 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 +0200950 }
951
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 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 +0200953
Gilles Peskine5197c662020-08-26 17:03:24 +0200954 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
956 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
957 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
958 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200959
Gilles Peskine5197c662020-08-26 17:03:24 +0200960 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200965
Gilles Peskine5197c662020-08-26 17:03:24 +0200966 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200971
Gilles Peskine5197c662020-08-26 17:03:24 +0200972 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
974 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
975 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200977
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
979 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
980 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
981 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000982
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986}
987#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
988
989/*
990 * AES-ECB block decryption
991 */
992#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100993int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
994 const unsigned char input[16],
995 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996{
997 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100998 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001000 uint32_t X[4];
1001 uint32_t Y[4];
1002 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1005 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1006 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1007 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1010 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]);
1011 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 +02001012 }
1013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 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 +02001015
Gilles Peskine5197c662020-08-26 17:03:24 +02001016 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1018 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1019 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1020 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001021
Gilles Peskine5197c662020-08-26 17:03:24 +02001022 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001027
Gilles Peskine5197c662020-08-26 17:03:24 +02001028 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001033
Gilles Peskine5197c662020-08-26 17:03:24 +02001034 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1036 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1037 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1041 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1042 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1043 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001046
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001048}
1049#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1050
Gilles Peskine0de8f852023-03-16 17:14:59 +01001051#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001052/* VIA Padlock and our intrinsics-based implementation of AESNI require
1053 * the round keys to be aligned on a 16-byte boundary. We take care of this
1054 * before creating them, but the AES context may have moved (this can happen
1055 * if the library is called from a language with managed memory), and in later
1056 * calls it might have a different alignment with respect to 16-byte memory.
1057 * So we may need to realign.
1058 */
1059static void aes_maybe_realign(mbedtls_aes_context *ctx)
1060{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001061 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1062 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001063 memmove(ctx->buf + new_offset, // new address
1064 ctx->buf + ctx->rk_offset, // current address
1065 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1066 ctx->rk_offset = new_offset;
1067 }
1068}
1069#endif
1070
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001071/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001072 * AES-ECB block encryption/decryption
1073 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001074int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1075 int mode,
1076 const unsigned char input[16],
1077 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001078{
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001080 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001082
Gilles Peskine0de8f852023-03-16 17:14:59 +01001083#if defined(MAY_NEED_TO_ALIGN)
1084 aes_maybe_realign(ctx);
1085#endif
1086
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001087#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1089 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1090 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001091#endif
1092
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001093#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001094 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001095 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1096 }
1097#endif
1098
Jerry Yu9e628622023-08-17 11:20:09 +08001099#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001101 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001102 }
1103#endif
1104
Jerry Yu29c91ba2023-08-04 11:02:04 +08001105#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 if (mode == MBEDTLS_AES_ENCRYPT) {
1107 return mbedtls_internal_aes_encrypt(ctx, input, output);
1108 } else {
1109 return mbedtls_internal_aes_decrypt(ctx, input, output);
1110 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001111#endif
1112
Paul Bakker5121ce52009-01-03 21:22:43 +00001113}
1114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001116
Paul Bakker5121ce52009-01-03 21:22:43 +00001117/*
1118 * AES-CBC buffer encryption/decryption
1119 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001120int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1121 int mode,
1122 size_t length,
1123 unsigned char iv[16],
1124 const unsigned char *input,
1125 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001126{
Gilles Peskine7820a572021-07-07 21:08:28 +02001127 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001128 unsigned char temp[16];
1129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001131 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001133
Paul Elliott2ad93672023-08-11 11:07:06 +01001134 /* Nothing to do if length is zero. */
1135 if (length == 0) {
1136 return 0;
1137 }
1138
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 if (length % 16) {
1140 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1141 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001142
Jerry Yu9e628622023-08-17 11:20:09 +08001143#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 if (aes_padlock_ace > 0) {
1145 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1146 return 0;
1147 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001148
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001149 // If padlock data misaligned, we just fall back to
1150 // unaccelerated mode
1151 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001152 }
1153#endif
1154
Dave Rodgman906c63c2023-06-14 17:53:51 +01001155 const unsigned char *ivp = iv;
1156
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 if (mode == MBEDTLS_AES_DECRYPT) {
1158 while (length > 0) {
1159 memcpy(temp, input, 16);
1160 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1161 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001162 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001164 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001165 * the result for the next block in CBC, and the cost of transferring that data from
1166 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001167 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001168
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001170
1171 input += 16;
1172 output += 16;
1173 length -= 16;
1174 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 } else {
1176 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001177 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001178
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1180 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001181 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001183 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001184
1185 input += 16;
1186 output += 16;
1187 length -= 16;
1188 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001189 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001190 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001191 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001192
Gilles Peskine7820a572021-07-07 21:08:28 +02001193exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001194 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001195}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001196#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001197
Aorimn5f778012016-06-09 23:22:58 +02001198#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001199
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001200typedef unsigned char mbedtls_be128[16];
1201
1202/*
1203 * GF(2^128) multiplication function
1204 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001205 * This function multiplies a field element by x in the polynomial field
1206 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001207 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001208 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001209 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001210#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001211MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001212#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001213static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001214 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001215{
1216 uint64_t a, b, ra, rb;
1217
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 a = MBEDTLS_GET_UINT64_LE(x, 0);
1219 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001220
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1222 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001223
Gilles Peskine449bd832023-01-11 14:50:10 +01001224 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1225 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001226}
1227
Aorimn5f778012016-06-09 23:22:58 +02001228/*
1229 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001230 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001231 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001232 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001233 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001234#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001235MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001236#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001237int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1238 int mode,
1239 size_t length,
1240 const unsigned char data_unit[16],
1241 const unsigned char *input,
1242 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001243{
Janos Follath24eed8d2019-11-22 13:21:35 +00001244 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001245 size_t blocks = length / 16;
1246 size_t leftover = length % 16;
1247 unsigned char tweak[16];
1248 unsigned char prev_tweak[16];
1249 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001250
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001252 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001254
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001255 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001257 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 }
Aorimn5f778012016-06-09 23:22:58 +02001259
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001260 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001262 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 }
Aorimn5f778012016-06-09 23:22:58 +02001264
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001266 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1267 data_unit, tweak);
1268 if (ret != 0) {
1269 return ret;
1270 }
Aorimn5f778012016-06-09 23:22:58 +02001271
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001273 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 /* We are on the last block in a decrypt operation that has
1275 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001276 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001277 * the leftovers and then update the current tweak for use on this,
1278 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 memcpy(prev_tweak, tweak, sizeof(tweak));
1280 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281 }
1282
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001284
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1286 if (ret != 0) {
1287 return ret;
1288 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001291
1292 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001294
1295 output += 16;
1296 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001297 }
1298
Gilles Peskine449bd832023-01-11 14:50:10 +01001299 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300 /* If we are on the leftover bytes in a decrypt operation, we need to
1301 * use the previous tweak for these bytes (as saved in prev_tweak). */
1302 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001303
Jaeden Amerod82cd862018-04-28 15:02:45 +01001304 /* We are now on the final part of the data unit, which doesn't divide
1305 * evenly by 16. It's time for ciphertext stealing. */
1306 size_t i;
1307 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001308
Jaeden Amerod82cd862018-04-28 15:02:45 +01001309 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001310 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001312 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001313 }
Aorimn5f778012016-06-09 23:22:58 +02001314
Dave Rodgman069e7f42022-11-24 19:37:26 +00001315 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001317
Jaeden Amerod82cd862018-04-28 15:02:45 +01001318 /* Copy ciphertext bytes from the previous block for input in this
1319 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001321
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1323 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001324 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 }
Aorimn5f778012016-06-09 23:22:58 +02001326
Jaeden Amerod82cd862018-04-28 15:02:45 +01001327 /* Write the result back to the previous block, overriding the previous
1328 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001330 }
1331
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001333}
1334#endif /* MBEDTLS_CIPHER_MODE_XTS */
1335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001336#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001337/*
1338 * AES-CFB128 buffer encryption/decryption
1339 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001340int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1341 int mode,
1342 size_t length,
1343 size_t *iv_off,
1344 unsigned char iv[16],
1345 const unsigned char *input,
1346 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001347{
Paul Bakker27fdf462011-06-09 13:55:13 +00001348 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001349 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001350 size_t n;
1351
Gilles Peskine449bd832023-01-11 14:50:10 +01001352 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001353 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001354 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001355
1356 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001357
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 if (n > 15) {
1359 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1360 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001361
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 if (mode == MBEDTLS_AES_DECRYPT) {
1363 while (length--) {
1364 if (n == 0) {
1365 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1366 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001367 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001369 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001370
1371 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001373 iv[n] = (unsigned char) c;
1374
Gilles Peskine449bd832023-01-11 14:50:10 +01001375 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001376 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 } else {
1378 while (length--) {
1379 if (n == 0) {
1380 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1381 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001382 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001384 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001385
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001387
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001389 }
1390 }
1391
1392 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001393 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001394
Gilles Peskine7820a572021-07-07 21:08:28 +02001395exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001397}
Paul Bakker556efba2014-01-24 15:38:12 +01001398
1399/*
1400 * AES-CFB8 buffer encryption/decryption
1401 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001402int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1403 int mode,
1404 size_t length,
1405 unsigned char iv[16],
1406 const unsigned char *input,
1407 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001408{
Gilles Peskine7820a572021-07-07 21:08:28 +02001409 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001410 unsigned char c;
1411 unsigned char ov[17];
1412
Gilles Peskine449bd832023-01-11 14:50:10 +01001413 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001414 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001415 }
1416 while (length--) {
1417 memcpy(ov, iv, 16);
1418 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1419 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001420 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 }
Paul Bakker556efba2014-01-24 15:38:12 +01001422
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001424 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 }
Paul Bakker556efba2014-01-24 15:38:12 +01001426
Gilles Peskine449bd832023-01-11 14:50:10 +01001427 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001428
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001430 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001431 }
Paul Bakker556efba2014-01-24 15:38:12 +01001432
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001434 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001435 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001436
Gilles Peskine7820a572021-07-07 21:08:28 +02001437exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001438 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001439}
Simon Butcher76a5b222018-04-22 22:57:27 +01001440#endif /* MBEDTLS_CIPHER_MODE_CFB */
1441
1442#if defined(MBEDTLS_CIPHER_MODE_OFB)
1443/*
1444 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1445 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001446int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1447 size_t length,
1448 size_t *iv_off,
1449 unsigned char iv[16],
1450 const unsigned char *input,
1451 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001452{
Simon Butcherad4e4932018-04-29 00:43:47 +01001453 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001454 size_t n;
1455
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001456 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001457
Gilles Peskine449bd832023-01-11 14:50:10 +01001458 if (n > 15) {
1459 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1460 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001461
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 while (length--) {
1463 if (n == 0) {
1464 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1465 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001466 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001467 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001468 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001469 *output++ = *input++ ^ iv[n];
1470
Gilles Peskine449bd832023-01-11 14:50:10 +01001471 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001472 }
1473
1474 *iv_off = n;
1475
Simon Butcherad4e4932018-04-29 00:43:47 +01001476exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001477 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001478}
1479#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001481#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001482/*
1483 * AES-CTR buffer encryption/decryption
1484 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001485int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1486 size_t length,
1487 size_t *nc_off,
1488 unsigned char nonce_counter[16],
1489 unsigned char stream_block[16],
1490 const unsigned char *input,
1491 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001492{
Paul Bakker369e14b2012-04-18 14:16:09 +00001493 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001494 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001495 size_t n;
1496
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001497 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001498
Gilles Peskine449bd832023-01-11 14:50:10 +01001499 if (n > 0x0F) {
1500 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1501 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001502
Gilles Peskine449bd832023-01-11 14:50:10 +01001503 while (length--) {
1504 if (n == 0) {
1505 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1506 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001507 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001508 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001509
Gilles Peskine449bd832023-01-11 14:50:10 +01001510 for (i = 16; i > 0; i--) {
1511 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001512 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001513 }
1514 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001515 }
1516 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001517 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001518
Gilles Peskine449bd832023-01-11 14:50:10 +01001519 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001520 }
1521
1522 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001523 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001524
Gilles Peskine7820a572021-07-07 21:08:28 +02001525exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001526 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001527}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001531
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001532#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001533/*
1534 * AES test vectors from:
1535 *
1536 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1537 */
Yanray Wang62c99912023-05-11 11:06:53 +08001538static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001539{
1540 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1541 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001542#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001543 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1544 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1545 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1546 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001547#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001548};
1549
Yanray Wang62c99912023-05-11 11:06:53 +08001550static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001551{
1552 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1553 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001554#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001555 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1556 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1557 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1558 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001559#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001560};
1561
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001562#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001563static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001564{
1565 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1566 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001567#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001568 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1569 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1570 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1571 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001572#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001573};
1574
Yanray Wang62c99912023-05-11 11:06:53 +08001575static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001576{
1577 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1578 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001579#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001580 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1581 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1582 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1583 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001584#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001585};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001586#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001587
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001588#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001589/*
1590 * AES-CFB128 test vectors from:
1591 *
1592 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1593 */
Yanray Wang62c99912023-05-11 11:06:53 +08001594static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001595{
1596 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1597 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001598#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001599 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1600 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1601 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1602 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1603 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1604 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1605 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001606#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001607};
1608
1609static const unsigned char aes_test_cfb128_iv[16] =
1610{
1611 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1612 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1613};
1614
1615static const unsigned char aes_test_cfb128_pt[64] =
1616{
1617 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1618 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1619 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1620 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1621 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1622 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1623 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1624 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1625};
1626
Yanray Wang62c99912023-05-11 11:06:53 +08001627static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001628{
1629 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1630 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1631 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1632 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1633 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1634 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1635 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1636 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001637#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001638 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1639 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1640 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1641 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1642 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1643 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1644 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1645 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1646 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1647 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1648 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1649 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1650 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1651 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1652 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1653 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001654#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001655};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001656#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001657
Simon Butcherad4e4932018-04-29 00:43:47 +01001658#if defined(MBEDTLS_CIPHER_MODE_OFB)
1659/*
1660 * AES-OFB test vectors from:
1661 *
Simon Butcher5db13622018-06-04 22:11:25 +01001662 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001663 */
Yanray Wang62c99912023-05-11 11:06:53 +08001664static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001665{
1666 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1667 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001668#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001669 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1670 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1671 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1672 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1673 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1674 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1675 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001676#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001677};
1678
1679static const unsigned char aes_test_ofb_iv[16] =
1680{
1681 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1682 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1683};
1684
1685static const unsigned char aes_test_ofb_pt[64] =
1686{
1687 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1688 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1689 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1690 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1691 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1692 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1693 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1694 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1695};
1696
Yanray Wang62c99912023-05-11 11:06:53 +08001697static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001698{
1699 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1700 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1701 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1702 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1703 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1704 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1705 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1706 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001707#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001708 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1709 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1710 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1711 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1712 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1713 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1714 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1715 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1716 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1717 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1718 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1719 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1720 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1721 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1722 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1723 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001724#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001725};
1726#endif /* MBEDTLS_CIPHER_MODE_OFB */
1727
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001728#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001729/*
1730 * AES-CTR test vectors from:
1731 *
1732 * http://www.faqs.org/rfcs/rfc3686.html
1733 */
1734
Yanray Wang62c99912023-05-11 11:06:53 +08001735static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001736{
1737 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1738 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1739 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1740 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1741 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1742 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1743};
1744
Yanray Wang62c99912023-05-11 11:06:53 +08001745static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001746{
1747 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1748 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1749 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1750 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1751 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1752 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1753};
1754
Yanray Wang62c99912023-05-11 11:06:53 +08001755static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001756{
1757 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1758 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001759 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1760 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1761 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1762 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1763
1764 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1765 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1766 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1767 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1768 0x20, 0x21, 0x22, 0x23 }
1769};
1770
Yanray Wang62c99912023-05-11 11:06:53 +08001771static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001772{
1773 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1774 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1775 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1776 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1777 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1778 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1779 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1780 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1781 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1782 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1783 0x25, 0xB2, 0x07, 0x2F }
1784};
1785
1786static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001787{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001788#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001789
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001790#if defined(MBEDTLS_CIPHER_MODE_XTS)
1791/*
1792 * AES-XTS test vectors from:
1793 *
1794 * IEEE P1619/D16 Annex B
1795 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1796 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1797 */
1798static const unsigned char aes_test_xts_key[][32] =
1799{
1800 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1804 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1805 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1806 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1807 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1808 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1809 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1810 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1811 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1812};
1813
1814static const unsigned char aes_test_xts_pt32[][32] =
1815{
1816 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1820 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1821 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1822 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1823 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1824 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1825 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1826 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1827 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1828};
1829
1830static const unsigned char aes_test_xts_ct32[][32] =
1831{
1832 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1833 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1834 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1835 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1836 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1837 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1838 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1839 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1840 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1841 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1842 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1843 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1844};
1845
1846static const unsigned char aes_test_xts_data_unit[][16] =
1847{
Gilles Peskine449bd832023-01-11 14:50:10 +01001848 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1850 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1851 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1852 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001854};
1855
1856#endif /* MBEDTLS_CIPHER_MODE_XTS */
1857
Paul Bakker5121ce52009-01-03 21:22:43 +00001858/*
1859 * Checkup routine
1860 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001861int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001862{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001863 int ret = 0, i, j, u, mode;
1864 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001865 unsigned char key[32];
1866 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001867 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001868#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1869 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001870 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001871#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001872#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001873 unsigned char prv[16];
1874#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001875#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1876 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001877 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001878#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001879#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001880 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001881#endif
1882#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001883 unsigned char nonce_counter[16];
1884 unsigned char stream_block[16];
1885#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001887
Gilles Peskine449bd832023-01-11 14:50:10 +01001888 memset(key, 0, 32);
1889 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001890
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001891 if (verbose != 0) {
1892#if defined(MBEDTLS_AES_ALT)
1893 mbedtls_printf(" AES note: alternative implementation.\n");
1894#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001895#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001896#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001897 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001898#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001899 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001900#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001901#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001902#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001903 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1904 mbedtls_printf(" AES note: using AESNI.\n");
1905 } else
1906#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001907#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001908 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1909 mbedtls_printf(" AES note: using VIA Padlock.\n");
1910 } else
1911#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001912#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001913 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001914 mbedtls_printf(" AES note: using AESCE.\n");
1915 } else
1916#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001917 {
1918#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1919 mbedtls_printf(" AES note: built-in implementation.\n");
1920#endif
1921 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001922#endif /* MBEDTLS_AES_ALT */
1923 }
1924
Paul Bakker5121ce52009-01-03 21:22:43 +00001925 /*
1926 * ECB mode
1927 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001928 {
1929 static const int num_tests =
1930 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001931
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001932 for (i = 0; i < num_tests << 1; i++) {
1933 u = i >> 1;
1934 keybits = 128 + u * 64;
1935 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001936
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001937 if (verbose != 0) {
1938 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1939 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1940 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001941
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001942 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001943
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001944 if (mode == MBEDTLS_AES_DECRYPT) {
1945 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1946 aes_tests = aes_test_ecb_dec[u];
1947 } else {
1948 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1949 aes_tests = aes_test_ecb_enc[u];
1950 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001951
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001952 /*
1953 * AES-192 is an optional feature that may be unavailable when
1954 * there is an alternative underlying implementation i.e. when
1955 * MBEDTLS_AES_ALT is defined.
1956 */
1957 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1958 mbedtls_printf("skipped\n");
1959 continue;
1960 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001961 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001962 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001963
1964 for (j = 0; j < 10000; j++) {
1965 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1966 if (ret != 0) {
1967 goto exit;
1968 }
1969 }
1970
1971 if (memcmp(buf, aes_tests, 16) != 0) {
1972 ret = 1;
1973 goto exit;
1974 }
1975
1976 if (verbose != 0) {
1977 mbedtls_printf("passed\n");
1978 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001979 }
1980
Gilles Peskine449bd832023-01-11 14:50:10 +01001981 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001982 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001983 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001984 }
1985
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001986#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001987 /*
1988 * CBC mode
1989 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001990 {
1991 static const int num_tests =
1992 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001993
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001994 for (i = 0; i < num_tests << 1; i++) {
1995 u = i >> 1;
1996 keybits = 128 + u * 64;
1997 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001998
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001999 if (verbose != 0) {
2000 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2001 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002002 }
2003
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002004 memset(iv, 0, 16);
2005 memset(prv, 0, 16);
2006 memset(buf, 0, 16);
2007
2008 if (mode == MBEDTLS_AES_DECRYPT) {
2009 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2010 aes_tests = aes_test_cbc_dec[u];
2011 } else {
2012 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2013 aes_tests = aes_test_cbc_enc[u];
2014 }
2015
2016 /*
2017 * AES-192 is an optional feature that may be unavailable when
2018 * there is an alternative underlying implementation i.e. when
2019 * MBEDTLS_AES_ALT is defined.
2020 */
2021 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2022 mbedtls_printf("skipped\n");
2023 continue;
2024 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002025 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002026 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002027
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002028 for (j = 0; j < 10000; j++) {
2029 if (mode == MBEDTLS_AES_ENCRYPT) {
2030 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002031
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002032 memcpy(tmp, prv, 16);
2033 memcpy(prv, buf, 16);
2034 memcpy(buf, tmp, 16);
2035 }
2036
2037 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2038 if (ret != 0) {
2039 goto exit;
2040 }
2041
2042 }
2043
2044 if (memcmp(buf, aes_tests, 16) != 0) {
2045 ret = 1;
2046 goto exit;
2047 }
2048
2049 if (verbose != 0) {
2050 mbedtls_printf("passed\n");
2051 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 }
2053
Gilles Peskine449bd832023-01-11 14:50:10 +01002054 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002055 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002056 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002057 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002058#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002059
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002060#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002061 /*
2062 * CFB128 mode
2063 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002064 {
2065 static const int num_tests =
2066 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002068 for (i = 0; i < num_tests << 1; i++) {
2069 u = i >> 1;
2070 keybits = 128 + u * 64;
2071 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002072
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002073 if (verbose != 0) {
2074 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2075 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2076 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002077
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002078 memcpy(iv, aes_test_cfb128_iv, 16);
2079 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002080
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002081 offset = 0;
2082 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2083 /*
2084 * AES-192 is an optional feature that may be unavailable when
2085 * there is an alternative underlying implementation i.e. when
2086 * MBEDTLS_AES_ALT is defined.
2087 */
2088 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2089 mbedtls_printf("skipped\n");
2090 continue;
2091 } else if (ret != 0) {
2092 goto exit;
2093 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002094
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002095 if (mode == MBEDTLS_AES_DECRYPT) {
2096 memcpy(buf, aes_test_cfb128_ct[u], 64);
2097 aes_tests = aes_test_cfb128_pt;
2098 } else {
2099 memcpy(buf, aes_test_cfb128_pt, 64);
2100 aes_tests = aes_test_cfb128_ct[u];
2101 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002102
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002103 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2104 if (ret != 0) {
2105 goto exit;
2106 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002107
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002108 if (memcmp(buf, aes_tests, 64) != 0) {
2109 ret = 1;
2110 goto exit;
2111 }
2112
2113 if (verbose != 0) {
2114 mbedtls_printf("passed\n");
2115 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002116 }
2117
Gilles Peskine449bd832023-01-11 14:50:10 +01002118 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002119 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002120 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002121 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002122#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002123
Simon Butcherad4e4932018-04-29 00:43:47 +01002124#if defined(MBEDTLS_CIPHER_MODE_OFB)
2125 /*
2126 * OFB mode
2127 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002128 {
2129 static const int num_tests =
2130 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002131
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002132 for (i = 0; i < num_tests << 1; i++) {
2133 u = i >> 1;
2134 keybits = 128 + u * 64;
2135 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002136
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002137 if (verbose != 0) {
2138 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2139 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2140 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002141
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002142 memcpy(iv, aes_test_ofb_iv, 16);
2143 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002144
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002145 offset = 0;
2146 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2147 /*
2148 * AES-192 is an optional feature that may be unavailable when
2149 * there is an alternative underlying implementation i.e. when
2150 * MBEDTLS_AES_ALT is defined.
2151 */
2152 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2153 mbedtls_printf("skipped\n");
2154 continue;
2155 } else if (ret != 0) {
2156 goto exit;
2157 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002158
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002159 if (mode == MBEDTLS_AES_DECRYPT) {
2160 memcpy(buf, aes_test_ofb_ct[u], 64);
2161 aes_tests = aes_test_ofb_pt;
2162 } else {
2163 memcpy(buf, aes_test_ofb_pt, 64);
2164 aes_tests = aes_test_ofb_ct[u];
2165 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002166
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002167 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2168 if (ret != 0) {
2169 goto exit;
2170 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002171
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002172 if (memcmp(buf, aes_tests, 64) != 0) {
2173 ret = 1;
2174 goto exit;
2175 }
2176
2177 if (verbose != 0) {
2178 mbedtls_printf("passed\n");
2179 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002180 }
2181
Gilles Peskine449bd832023-01-11 14:50:10 +01002182 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002183 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002184 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002185 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002186#endif /* MBEDTLS_CIPHER_MODE_OFB */
2187
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002188#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002189 /*
2190 * CTR mode
2191 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002192 {
2193 static const int num_tests =
2194 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 for (i = 0; i < num_tests << 1; i++) {
2197 u = i >> 1;
2198 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002199
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002200 if (verbose != 0) {
2201 mbedtls_printf(" AES-CTR-128 (%s): ",
2202 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2203 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002204
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002205 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2206 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002207
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002208 offset = 0;
2209 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2210 goto exit;
2211 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002212
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002213 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002214
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002215 if (mode == MBEDTLS_AES_DECRYPT) {
2216 memcpy(buf, aes_test_ctr_ct[u], len);
2217 aes_tests = aes_test_ctr_pt[u];
2218 } else {
2219 memcpy(buf, aes_test_ctr_pt[u], len);
2220 aes_tests = aes_test_ctr_ct[u];
2221 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002222
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002223 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2224 stream_block, buf, buf);
2225 if (ret != 0) {
2226 goto exit;
2227 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002228
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002229 if (memcmp(buf, aes_tests, len) != 0) {
2230 ret = 1;
2231 goto exit;
2232 }
2233
2234 if (verbose != 0) {
2235 mbedtls_printf("passed\n");
2236 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002237 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002238 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002239
Gilles Peskine449bd832023-01-11 14:50:10 +01002240 if (verbose != 0) {
2241 mbedtls_printf("\n");
2242 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002243#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002244
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002245#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002246 /*
2247 * XTS mode
2248 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002249 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002250 static const int num_tests =
2251 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2252 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002253
Gilles Peskine449bd832023-01-11 14:50:10 +01002254 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002255
Gilles Peskine449bd832023-01-11 14:50:10 +01002256 for (i = 0; i < num_tests << 1; i++) {
2257 const unsigned char *data_unit;
2258 u = i >> 1;
2259 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002260
Gilles Peskine449bd832023-01-11 14:50:10 +01002261 if (verbose != 0) {
2262 mbedtls_printf(" AES-XTS-128 (%s): ",
2263 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2264 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002265
Gilles Peskine449bd832023-01-11 14:50:10 +01002266 memset(key, 0, sizeof(key));
2267 memcpy(key, aes_test_xts_key[u], 32);
2268 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002269
Gilles Peskine449bd832023-01-11 14:50:10 +01002270 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002271
Gilles Peskine449bd832023-01-11 14:50:10 +01002272 if (mode == MBEDTLS_AES_DECRYPT) {
2273 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2274 if (ret != 0) {
2275 goto exit;
2276 }
2277 memcpy(buf, aes_test_xts_ct32[u], len);
2278 aes_tests = aes_test_xts_pt32[u];
2279 } else {
2280 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2281 if (ret != 0) {
2282 goto exit;
2283 }
2284 memcpy(buf, aes_test_xts_pt32[u], len);
2285 aes_tests = aes_test_xts_ct32[u];
2286 }
2287
2288
2289 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2290 buf, buf);
2291 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002292 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002293 }
2294
2295 if (memcmp(buf, aes_tests, len) != 0) {
2296 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002297 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002298 }
2299
2300 if (verbose != 0) {
2301 mbedtls_printf("passed\n");
2302 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002303 }
2304
Gilles Peskine449bd832023-01-11 14:50:10 +01002305 if (verbose != 0) {
2306 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002307 }
2308
Gilles Peskine449bd832023-01-11 14:50:10 +01002309 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002310 }
2311#endif /* MBEDTLS_CIPHER_MODE_XTS */
2312
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002313 ret = 0;
2314
2315exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002316 if (ret != 0 && verbose != 0) {
2317 mbedtls_printf("failed\n");
2318 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002319
Gilles Peskine449bd832023-01-11 14:50:10 +01002320 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002321
Gilles Peskine449bd832023-01-11 14:50:10 +01002322 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002323}
2324
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002325#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002327#endif /* MBEDTLS_AES_C */