blob: 29a193e70c601420cedb8d23c4e3ec3683a0443a [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
Dave Rodgman782df0352023-09-29 12:57:52 +010037#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
38#if !((defined(MBEDTLS_ARCH_IS_ARM64) && defined(MBEDTLS_AESCE_C)) || \
Dave Rodgmana06d45e2023-09-29 18:59:34 +010039 (defined(MBEDTLS_ARCH_IS_X64) && defined(MBEDTLS_AESNI_C)) || \
40 (defined(MBEDTLS_ARCH_IS_X86) && defined(MBEDTLS_AESNI_C)))
Jerry Yu69436812023-04-25 11:08:30 +080041#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080042#endif
43#endif
44
Dave Rodgmane81a6322023-09-29 13:54:27 +010045#if defined(MBEDTLS_ARCH_IS_X86)
Jerry Yu61fc5ed2023-08-18 17:28:48 +080046#if defined(MBEDTLS_PADLOCK_C)
47#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080048#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
49#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080050#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
51#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
52 "MBEDTLS_PADLOCK_C is set"
53#endif
54#endif
Jerry Yu02b15192023-04-23 14:43:19 +080055#endif
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000058#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000059#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000061#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010062#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080063#if defined(MBEDTLS_AESCE_C)
64#include "aesce.h"
65#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000066
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068
Yanray Wangdbcc0c62023-08-30 15:04:01 +080069#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)) && \
Yanray Wangb67b4742023-10-31 17:10:32 +080070 !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wangdbcc0c62023-08-30 15:04:01 +080071#define MBEDTLS_AES_NEED_REVERSE_TABLES
72#endif
73
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020075
Jerry Yu9e628622023-08-17 11:20:09 +080076#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000077static int aes_padlock_ace = -1;
78#endif
79
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000081/*
82 * Forward S-box
83 */
Dave Rodgman18ddf612023-10-04 14:03:12 +010084MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +000085{
86 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
87 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
88 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
89 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
90 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
91 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
92 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
93 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
94 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
95 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
96 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
97 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
98 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
99 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
100 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
101 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
102 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
103 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
104 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
105 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
106 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
107 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
108 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
109 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
110 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
111 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
112 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
113 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
114 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
115 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
116 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
117 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
118};
119
120/*
121 * Forward tables
122 */
123#define FT \
124\
Gilles Peskine449bd832023-01-11 14:50:10 +0100125 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
126 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
127 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
128 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
129 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
130 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
131 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
132 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
133 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
134 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
135 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
136 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
137 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
138 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
139 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
140 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
141 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
142 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
143 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
144 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
145 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
146 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
147 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
148 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
149 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
150 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
151 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
152 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
153 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
154 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
155 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
156 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
157 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
158 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
159 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
160 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
161 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
162 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
163 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
164 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
165 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
166 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
167 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
168 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
169 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
170 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
171 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
172 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
173 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
174 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
175 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
176 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
177 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
178 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
179 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
180 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
181 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
182 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
183 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
184 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
185 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
186 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
187 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
188 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 +0000189
Gilles Peskine449bd832023-01-11 14:50:10 +0100190#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100191MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000192#undef V
193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100195MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000196#undef V
197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100199MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000200#undef V
201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100203MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000204#undef V
205
206#undef FT
207
208/*
209 * Reverse S-box
210 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100211MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000212{
213 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
214 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
215 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
216 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
217 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
218 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
219 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
220 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
221 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
222 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
223 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
224 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
225 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
226 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
227 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
228 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
229 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
230 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
231 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
232 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
233 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
234 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
235 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
236 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
237 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
238 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
239 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
240 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
241 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
242 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
243 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
244 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
245};
246
247/*
248 * Reverse tables
249 */
250#define RT \
251\
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
253 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
254 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
255 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
256 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
257 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
258 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
259 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
260 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
261 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
262 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
263 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
264 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
265 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
266 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
267 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
268 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
269 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
270 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
271 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
272 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
273 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
274 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
275 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
276 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
277 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
278 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
279 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
280 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
281 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
282 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
283 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
284 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
285 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
286 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
287 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
288 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
289 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
290 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
291 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
292 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
293 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
294 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
295 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
296 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
297 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
298 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
299 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
300 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
301 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
302 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
303 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
304 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
305 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
306 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
307 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
308 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
309 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
310 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
311 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
312 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
313 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
314 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
315 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 +0000316
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100317
Gilles Peskine449bd832023-01-11 14:50:10 +0100318#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100319MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000320#undef V
321
Gilles Peskine449bd832023-01-11 14:50:10 +0100322#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100323MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000324#undef V
325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100327MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000328#undef V
329
Gilles Peskine449bd832023-01-11 14:50:10 +0100330#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100331MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000332#undef V
333
334#undef RT
335
336/*
337 * Round constants
338 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100339MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000340{
341 0x00000001, 0x00000002, 0x00000004, 0x00000008,
342 0x00000010, 0x00000020, 0x00000040, 0x00000080,
343 0x0000001B, 0x00000036
344};
345
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
348/*
349 * Forward S-box & tables
350 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100351MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
352MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
353MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
354MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
355MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357/*
358 * Reverse S-box & tables
359 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100360MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100361
Dave Rodgman18ddf612023-10-04 14:03:12 +0100362MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
363MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
364MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
365MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367/*
368 * Round constants
369 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100370MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
372/*
373 * Tables generation code
374 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
376#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
377#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
Dave Rodgman18ddf612023-10-04 14:03:12 +0100379MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000380
Dave Rodgman18ddf612023-10-04 14:03:12 +0100381MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000382{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800383 int i;
384 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800385 uint8_t pow[256];
386 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
388 /*
389 * compute pow and log tables over GF(2^8)
390 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000392 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800393 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800394 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 }
396
397 /*
398 * calculate the round constants
399 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200401 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800402 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 }
404
405 /*
406 * generate the forward and reverse S-boxes
407 */
408 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800409#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000410 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800411#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 x = pow[255 - log[i]];
415
Yanray Wangfe944ce2023-06-26 18:16:01 +0800416 y = x; y = (y << 1) | (y >> 7);
417 x ^= y; y = (y << 1) | (y >> 7);
418 x ^= y; y = (y << 1) | (y >> 7);
419 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 x ^= y ^ 0x63;
421
Yanray Wangfe944ce2023-06-26 18:16:01 +0800422 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800423#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800425#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 }
427
428 /*
429 * generate the forward and reverse tables
430 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800433 y = XTIME(x);
434 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 FT0[i] = ((uint32_t) y) ^
437 ((uint32_t) x << 8) ^
438 ((uint32_t) x << 16) ^
439 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Hanno Beckerad049a92017-06-19 16:31:54 +0100441#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 FT1[i] = ROTL8(FT0[i]);
443 FT2[i] = ROTL8(FT1[i]);
444 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100445#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800447#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000448 x = RSb[i];
449
Yanray Wang4b6595a2023-10-17 11:01:25 +0800450#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
452 ((uint32_t) MUL(0x09, x) << 8) ^
453 ((uint32_t) MUL(0x0D, x) << 16) ^
454 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
Hanno Beckerad049a92017-06-19 16:31:54 +0100456#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 RT1[i] = ROTL8(RT0[i]);
458 RT2[i] = ROTL8(RT1[i]);
459 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100460#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wang4b6595a2023-10-17 11:01:25 +0800461#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800462#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 }
464}
465
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200466#undef ROTL8
467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Hanno Beckerad049a92017-06-19 16:31:54 +0100470#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200471
Gilles Peskine449bd832023-01-11 14:50:10 +0100472#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
473#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
474#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200475
476#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100477#define AES_RT1(idx) ROTL8(RT0[idx])
478#define AES_RT2(idx) ROTL16(RT0[idx])
479#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200480
481#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100482#define AES_FT1(idx) ROTL8(FT0[idx])
483#define AES_FT2(idx) ROTL16(FT0[idx])
484#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200485
Hanno Becker177d3cf2017-06-07 15:52:48 +0100486#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200487
488#define AES_RT0(idx) RT0[idx]
489#define AES_RT1(idx) RT1[idx]
490#define AES_RT2(idx) RT2[idx]
491#define AES_RT3(idx) RT3[idx]
492
493#define AES_FT0(idx) FT0[idx]
494#define AES_FT1(idx) FT1[idx]
495#define AES_FT2(idx) FT2[idx]
496#define AES_FT3(idx) FT3[idx]
497
Hanno Becker177d3cf2017-06-07 15:52:48 +0100498#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200501{
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200503}
504
Gilles Peskine449bd832023-01-11 14:50:10 +0100505void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200506{
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200508 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200510
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200512}
513
Jaeden Amero9366feb2018-05-29 18:55:17 +0100514#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100515void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100516{
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 mbedtls_aes_init(&ctx->crypt);
518 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100519}
520
Gilles Peskine449bd832023-01-11 14:50:10 +0100521void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100522{
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100524 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 }
Simon Butcher5201e412018-12-06 17:40:14 +0000526
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 mbedtls_aes_free(&ctx->crypt);
528 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100529}
530#endif /* MBEDTLS_CIPHER_MODE_XTS */
531
Gilles Peskine0de8f852023-03-16 17:14:59 +0100532/* Some implementations need the round keys to be aligned.
533 * Return an offset to be added to buf, such that (buf + offset) is
534 * correctly aligned.
535 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
536 * i.e. an offset of 1 means 4 bytes and so on.
537 */
Jerry Yu96084472023-08-17 18:10:45 +0800538#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100539 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100540#define MAY_NEED_TO_ALIGN
541#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100542
Dave Rodgman18ddf612023-10-04 14:03:12 +0100543MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100544{
545#if defined(MAY_NEED_TO_ALIGN)
546 int align_16_bytes = 0;
547
Jerry Yu9e628622023-08-17 11:20:09 +0800548#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100549 if (aes_padlock_ace == -1) {
550 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
551 }
552 if (aes_padlock_ace) {
553 align_16_bytes = 1;
554 }
555#endif
556
Gilles Peskine9c682e72023-03-16 17:21:33 +0100557#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100558 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
559 align_16_bytes = 1;
560 }
561#endif
562
563 if (align_16_bytes) {
564 /* These implementations needs 16-byte alignment
565 * for the round key array. */
566 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
567 if (delta == 0) {
568 return 0;
569 } else {
570 return 4 - delta; // 16 bytes = 4 uint32_t
571 }
572 }
573#else /* MAY_NEED_TO_ALIGN */
574 (void) buf;
575#endif /* MAY_NEED_TO_ALIGN */
576
577 return 0;
578}
579
Paul Bakker5121ce52009-01-03 21:22:43 +0000580/*
581 * AES key schedule (encryption)
582 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200583#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100584int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
585 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000586{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000587 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000588
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000590 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800591#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000592 case 192: ctx->nr = 12; break;
593 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800594#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 }
597
Simon Butcher5201e412018-12-06 17:40:14 +0000598#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000600 aes_gen_tables();
601 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000602 }
603#endif
604
Gilles Peskine0de8f852023-03-16 17:14:59 +0100605 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100606 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100608#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
610 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
611 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100612#endif
613
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800614#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100615 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800616 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
617 }
618#endif
619
Jerry Yu29c91ba2023-08-04 11:02:04 +0800620#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800621 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000623 }
624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000626 case 10:
627
Jerry Yu3a0f0442023-08-17 17:06:21 +0800628 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200629 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
631 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
632 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
633 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 RK[5] = RK[1] ^ RK[4];
636 RK[6] = RK[2] ^ RK[5];
637 RK[7] = RK[3] ^ RK[6];
638 }
639 break;
640
Arto Kinnunen732ca322023-04-14 14:26:10 +0800641#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000642 case 12:
643
Jerry Yu3a0f0442023-08-17 17:06:21 +0800644 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200645 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
647 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
648 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
649 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000650
651 RK[7] = RK[1] ^ RK[6];
652 RK[8] = RK[2] ^ RK[7];
653 RK[9] = RK[3] ^ RK[8];
654 RK[10] = RK[4] ^ RK[9];
655 RK[11] = RK[5] ^ RK[10];
656 }
657 break;
658
659 case 14:
660
Jerry Yu3a0f0442023-08-17 17:06:21 +0800661 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200662 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
664 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
665 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
666 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
668 RK[9] = RK[1] ^ RK[8];
669 RK[10] = RK[2] ^ RK[9];
670 RK[11] = RK[3] ^ RK[10];
671
672 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
674 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
675 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
676 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678 RK[13] = RK[5] ^ RK[12];
679 RK[14] = RK[6] ^ RK[13];
680 RK[15] = RK[7] ^ RK[14];
681 }
682 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800683#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000684 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800687#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000688}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200689#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000690
691/*
692 * AES key schedule (decryption)
693 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800694#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100695int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
696 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000697{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800698#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800699 uint32_t *SK;
700#endif
701 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200702 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000703 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800704
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000707
Gilles Peskine0de8f852023-03-16 17:14:59 +0100708 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100709 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000710
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200711 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200713 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000715
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200716 ctx->nr = cty.nr;
717
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100718#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
720 mbedtls_aesni_inverse_key((unsigned char *) RK,
721 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200722 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100723 }
724#endif
725
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800726#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100727 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800728 mbedtls_aesce_inverse_key(
729 (unsigned char *) RK,
730 (const unsigned char *) (cty.buf + cty.rk_offset),
731 ctx->nr);
732 goto exit;
733 }
734#endif
735
Jerry Yu29c91ba2023-08-04 11:02:04 +0800736#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100737 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000738
739 *RK++ = *SK++;
740 *RK++ = *SK++;
741 *RK++ = *SK++;
742 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800743 SK -= 8;
744 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
745 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
747 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
748 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
749 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000750 }
751 }
752
753 *RK++ = *SK++;
754 *RK++ = *SK++;
755 *RK++ = *SK++;
756 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800757#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200758exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000760
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000762}
Yanray Wangb67b4742023-10-31 17:10:32 +0800763#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100764
765#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100766static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
767 unsigned int keybits,
768 const unsigned char **key1,
769 unsigned int *key1bits,
770 const unsigned char **key2,
771 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100772{
773 const unsigned int half_keybits = keybits / 2;
774 const unsigned int half_keybytes = half_keybits / 8;
775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100777 case 256: break;
778 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100780 }
781
782 *key1bits = half_keybits;
783 *key2bits = half_keybits;
784 *key1 = &key[0];
785 *key2 = &key[half_keybytes];
786
787 return 0;
788}
789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
791 const unsigned char *key,
792 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100793{
Janos Follath24eed8d2019-11-22 13:21:35 +0000794 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100795 const unsigned char *key1, *key2;
796 unsigned int key1bits, key2bits;
797
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
799 &key2, &key2bits);
800 if (ret != 0) {
801 return ret;
802 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100803
804 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
806 if (ret != 0) {
807 return ret;
808 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100809
810 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100812}
813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
815 const unsigned char *key,
816 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100817{
Janos Follath24eed8d2019-11-22 13:21:35 +0000818 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100819 const unsigned char *key1, *key2;
820 unsigned int key1bits, key2bits;
821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
823 &key2, &key2bits);
824 if (ret != 0) {
825 return ret;
826 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100827
828 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
830 if (ret != 0) {
831 return ret;
832 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100833
834 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100836}
837#endif /* MBEDTLS_CIPHER_MODE_XTS */
838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100840 do \
841 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
843 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
844 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
845 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100846 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
848 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
849 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
850 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100851 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
853 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
854 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
855 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100856 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
858 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
859 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
860 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
861 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100864 do \
865 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
867 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
868 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
869 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100870 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
872 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
873 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
874 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100875 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
877 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
878 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
879 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100880 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
882 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
883 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
884 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
885 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
887/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200888 * AES-ECB block encryption
889 */
890#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100891int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
892 const unsigned char input[16],
893 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200894{
895 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100896 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200898 uint32_t X[4];
899 uint32_t Y[4];
900 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
903 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
904 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
905 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
908 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]);
909 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 +0200910 }
911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 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 +0200913
Gilles Peskine5197c662020-08-26 17:03:24 +0200914 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
916 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
917 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
918 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200919
Gilles Peskine5197c662020-08-26 17:03:24 +0200920 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
922 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
923 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
924 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200925
Gilles Peskine5197c662020-08-26 17:03:24 +0200926 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
928 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
929 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
930 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200931
Gilles Peskine5197c662020-08-26 17:03:24 +0200932 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
934 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
935 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
936 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200937
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
939 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
940 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
941 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200946}
947#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
948
949/*
950 * AES-ECB block decryption
951 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800952#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100953int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
954 const unsigned char input[16],
955 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200956{
957 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100958 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200960 uint32_t X[4];
961 uint32_t Y[4];
962 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200963
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
965 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
966 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
967 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
970 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]);
971 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 +0200972 }
973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 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 +0200975
Gilles Peskine5197c662020-08-26 17:03:24 +0200976 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
978 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
979 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
980 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200981
Gilles Peskine5197c662020-08-26 17:03:24 +0200982 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
986 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200987
Gilles Peskine5197c662020-08-26 17:03:24 +0200988 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
992 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200993
Gilles Peskine5197c662020-08-26 17:03:24 +0200994 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
998 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1001 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1002 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1003 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001008}
Yanray Wangb67b4742023-10-31 17:10:32 +08001009#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001010
Gilles Peskine148cad12023-03-16 13:08:42 +01001011/* VIA Padlock and our intrinsics-based implementation of AESNI require
1012 * the round keys to be aligned on a 16-byte boundary. We take care of this
1013 * before creating them, but the AES context may have moved (this can happen
1014 * if the library is called from a language with managed memory), and in later
1015 * calls it might have a different alignment with respect to 16-byte memory.
1016 * So we may need to realign.
1017 */
Dave Rodgman18ddf612023-10-04 14:03:12 +01001018MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +01001019{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001020 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1021 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001022 memmove(ctx->buf + new_offset, // new address
1023 ctx->buf + ctx->rk_offset, // current address
1024 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1025 ctx->rk_offset = new_offset;
1026 }
1027}
Gilles Peskine148cad12023-03-16 13:08:42 +01001028
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001029/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001030 * AES-ECB block encryption/decryption
1031 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001032int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1033 int mode,
1034 const unsigned char input[16],
1035 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001036{
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001038 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001040
Gilles Peskine0de8f852023-03-16 17:14:59 +01001041#if defined(MAY_NEED_TO_ALIGN)
1042 aes_maybe_realign(ctx);
1043#endif
1044
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001045#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1047 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1048 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001049#endif
1050
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001051#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001052 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001053 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1054 }
1055#endif
1056
Jerry Yu9e628622023-08-17 11:20:09 +08001057#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001059 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 }
1061#endif
1062
Jerry Yu29c91ba2023-08-04 11:02:04 +08001063#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 if (mode == MBEDTLS_AES_ENCRYPT) {
1065 return mbedtls_internal_aes_encrypt(ctx, input, output);
1066 } else {
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001067#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang78ee0c92023-05-15 11:23:50 +08001069#else
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001070 return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
Jerry Yu29c91ba2023-08-04 11:02:04 +08001071#endif
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001072 }
1073 return mbedtls_internal_aes_encrypt(ctx, input, output);
Yanray Wang78ee0c92023-05-15 11:23:50 +08001074#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001075}
1076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001078
Paul Bakker5121ce52009-01-03 21:22:43 +00001079/*
1080 * AES-CBC buffer encryption/decryption
1081 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001082int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1083 int mode,
1084 size_t length,
1085 unsigned char iv[16],
1086 const unsigned char *input,
1087 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001088{
Gilles Peskine7820a572021-07-07 21:08:28 +02001089 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001090 unsigned char temp[16];
1091
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001093 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001095
Paul Elliott2ad93672023-08-11 11:07:06 +01001096 /* Nothing to do if length is zero. */
1097 if (length == 0) {
1098 return 0;
1099 }
1100
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 if (length % 16) {
1102 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1103 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001104
Jerry Yu9e628622023-08-17 11:20:09 +08001105#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 if (aes_padlock_ace > 0) {
1107 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1108 return 0;
1109 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001110
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001111 // If padlock data misaligned, we just fall back to
1112 // unaccelerated mode
1113 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001114 }
1115#endif
1116
Dave Rodgman906c63c2023-06-14 17:53:51 +01001117 const unsigned char *ivp = iv;
1118
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 if (mode == MBEDTLS_AES_DECRYPT) {
1120 while (length > 0) {
1121 memcpy(temp, input, 16);
1122 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1123 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001124 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001126 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001127 * the result for the next block in CBC, and the cost of transferring that data from
1128 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001129 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001132
1133 input += 16;
1134 output += 16;
1135 length -= 16;
1136 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 } else {
1138 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001139 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001140
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1142 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001143 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001145 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001146
1147 input += 16;
1148 output += 16;
1149 length -= 16;
1150 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001151 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001152 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001153 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001154
Gilles Peskine7820a572021-07-07 21:08:28 +02001155exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001157}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001159
Aorimn5f778012016-06-09 23:22:58 +02001160#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001161
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001162typedef unsigned char mbedtls_be128[16];
1163
1164/*
1165 * GF(2^128) multiplication function
1166 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001167 * This function multiplies a field element by x in the polynomial field
1168 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001169 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001170 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001171 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001172#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001173MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001174#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001175static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001176 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001177{
1178 uint64_t a, b, ra, rb;
1179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 a = MBEDTLS_GET_UINT64_LE(x, 0);
1181 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001182
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1184 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001185
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1187 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001188}
1189
Aorimn5f778012016-06-09 23:22:58 +02001190/*
1191 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001192 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001193 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001194 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001195 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001196#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001197MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001198#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001199int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1200 int mode,
1201 size_t length,
1202 const unsigned char data_unit[16],
1203 const unsigned char *input,
1204 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001205{
Janos Follath24eed8d2019-11-22 13:21:35 +00001206 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001207 size_t blocks = length / 16;
1208 size_t leftover = length % 16;
1209 unsigned char tweak[16];
1210 unsigned char prev_tweak[16];
1211 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001212
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001214 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001216
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001217 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001219 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 }
Aorimn5f778012016-06-09 23:22:58 +02001221
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001222 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001224 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 }
Aorimn5f778012016-06-09 23:22:58 +02001226
Jaeden Amerod82cd862018-04-28 15:02:45 +01001227 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1229 data_unit, tweak);
1230 if (ret != 0) {
1231 return ret;
1232 }
Aorimn5f778012016-06-09 23:22:58 +02001233
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001235 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001236 /* We are on the last block in a decrypt operation that has
1237 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001238 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239 * the leftovers and then update the current tweak for use on this,
1240 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 memcpy(prev_tweak, tweak, sizeof(tweak));
1242 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001243 }
1244
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001246
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1248 if (ret != 0) {
1249 return ret;
1250 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001251
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253
1254 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256
1257 output += 16;
1258 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001259 }
1260
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 /* If we are on the leftover bytes in a decrypt operation, we need to
1263 * use the previous tweak for these bytes (as saved in prev_tweak). */
1264 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001265
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 /* We are now on the final part of the data unit, which doesn't divide
1267 * evenly by 16. It's time for ciphertext stealing. */
1268 size_t i;
1269 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001270
Jaeden Amerod82cd862018-04-28 15:02:45 +01001271 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001272 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001275 }
Aorimn5f778012016-06-09 23:22:58 +02001276
Dave Rodgman069e7f42022-11-24 19:37:26 +00001277 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001279
Jaeden Amerod82cd862018-04-28 15:02:45 +01001280 /* Copy ciphertext bytes from the previous block for input in this
1281 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001283
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1285 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001286 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 }
Aorimn5f778012016-06-09 23:22:58 +02001288
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289 /* Write the result back to the previous block, overriding the previous
1290 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001292 }
1293
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001295}
1296#endif /* MBEDTLS_CIPHER_MODE_XTS */
1297
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001298#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001299/*
1300 * AES-CFB128 buffer encryption/decryption
1301 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001302int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1303 int mode,
1304 size_t length,
1305 size_t *iv_off,
1306 unsigned char iv[16],
1307 const unsigned char *input,
1308 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001309{
Paul Bakker27fdf462011-06-09 13:55:13 +00001310 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001311 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001312 size_t n;
1313
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001315 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001317
1318 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001319
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 if (n > 15) {
1321 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1322 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001323
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 if (mode == MBEDTLS_AES_DECRYPT) {
1325 while (length--) {
1326 if (n == 0) {
1327 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1328 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001329 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001331 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001332
1333 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001335 iv[n] = (unsigned char) c;
1336
Gilles Peskine449bd832023-01-11 14:50:10 +01001337 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 } else {
1340 while (length--) {
1341 if (n == 0) {
1342 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1343 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001344 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001346 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001347
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001349
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001351 }
1352 }
1353
1354 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001355 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001356
Gilles Peskine7820a572021-07-07 21:08:28 +02001357exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001359}
Paul Bakker556efba2014-01-24 15:38:12 +01001360
1361/*
1362 * AES-CFB8 buffer encryption/decryption
1363 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001364int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1365 int mode,
1366 size_t length,
1367 unsigned char iv[16],
1368 const unsigned char *input,
1369 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001370{
Gilles Peskine7820a572021-07-07 21:08:28 +02001371 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001372 unsigned char c;
1373 unsigned char ov[17];
1374
Gilles Peskine449bd832023-01-11 14:50:10 +01001375 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001376 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 }
1378 while (length--) {
1379 memcpy(ov, iv, 16);
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 }
Paul Bakker556efba2014-01-24 15:38:12 +01001384
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001386 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 }
Paul Bakker556efba2014-01-24 15:38:12 +01001388
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001390
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001392 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 }
Paul Bakker556efba2014-01-24 15:38:12 +01001394
Gilles Peskine449bd832023-01-11 14:50:10 +01001395 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001396 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001397 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001398
Gilles Peskine7820a572021-07-07 21:08:28 +02001399exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001400 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001401}
Simon Butcher76a5b222018-04-22 22:57:27 +01001402#endif /* MBEDTLS_CIPHER_MODE_CFB */
1403
1404#if defined(MBEDTLS_CIPHER_MODE_OFB)
1405/*
1406 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1407 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001408int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1409 size_t length,
1410 size_t *iv_off,
1411 unsigned char iv[16],
1412 const unsigned char *input,
1413 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001414{
Simon Butcherad4e4932018-04-29 00:43:47 +01001415 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001416 size_t n;
1417
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001418 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001419
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 if (n > 15) {
1421 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1422 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001423
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 while (length--) {
1425 if (n == 0) {
1426 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1427 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001428 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001430 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001431 *output++ = *input++ ^ iv[n];
1432
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001434 }
1435
1436 *iv_off = n;
1437
Simon Butcherad4e4932018-04-29 00:43:47 +01001438exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001439 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001440}
1441#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001444/*
1445 * AES-CTR buffer encryption/decryption
1446 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001447int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1448 size_t length,
1449 size_t *nc_off,
1450 unsigned char nonce_counter[16],
1451 unsigned char stream_block[16],
1452 const unsigned char *input,
1453 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001454{
Paul Bakker369e14b2012-04-18 14:16:09 +00001455 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001456 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001457 size_t n;
1458
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001459 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001460
Gilles Peskine449bd832023-01-11 14:50:10 +01001461 if (n > 0x0F) {
1462 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1463 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001464
Gilles Peskine449bd832023-01-11 14:50:10 +01001465 while (length--) {
1466 if (n == 0) {
1467 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1468 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001469 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001470 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001471
Gilles Peskine449bd832023-01-11 14:50:10 +01001472 for (i = 16; i > 0; i--) {
1473 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001474 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001475 }
1476 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477 }
1478 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001479 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001480
Gilles Peskine449bd832023-01-11 14:50:10 +01001481 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001482 }
1483
1484 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001485 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001486
Gilles Peskine7820a572021-07-07 21:08:28 +02001487exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001488 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001492#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001495/*
1496 * AES test vectors from:
1497 *
1498 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1499 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001500#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001501static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001502{
1503 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1504 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001505#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001506 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1507 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1508 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1509 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001510#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001511};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001512#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001513
Yanray Wang62c99912023-05-11 11:06:53 +08001514static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001515{
1516 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1517 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001518#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001519 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1520 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1521 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1522 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001523#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001524};
1525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001527static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001528{
1529 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1530 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001531#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001532 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1533 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1534 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1535 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001536#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001537};
1538
Yanray Wang62c99912023-05-11 11:06:53 +08001539static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001540{
1541 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1542 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001543#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001544 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1545 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1546 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1547 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001548#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001549};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001550#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001552#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001553/*
1554 * AES-CFB128 test vectors from:
1555 *
1556 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1557 */
Yanray Wang62c99912023-05-11 11:06:53 +08001558static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001559{
1560 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1561 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001562#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001563 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1564 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1565 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1566 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1567 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1568 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1569 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001570#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001571};
1572
1573static const unsigned char aes_test_cfb128_iv[16] =
1574{
1575 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1576 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1577};
1578
1579static const unsigned char aes_test_cfb128_pt[64] =
1580{
1581 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1582 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1583 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1584 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1585 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1586 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1587 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1588 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1589};
1590
Yanray Wang62c99912023-05-11 11:06:53 +08001591static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001592{
1593 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1594 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1595 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1596 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1597 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1598 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1599 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1600 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001601#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001602 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1603 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1604 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1605 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1606 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1607 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1608 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1609 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1610 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1611 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1612 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1613 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1614 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1615 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1616 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1617 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001618#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001619};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001620#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001621
Simon Butcherad4e4932018-04-29 00:43:47 +01001622#if defined(MBEDTLS_CIPHER_MODE_OFB)
1623/*
1624 * AES-OFB test vectors from:
1625 *
Simon Butcher5db13622018-06-04 22:11:25 +01001626 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001627 */
Yanray Wang62c99912023-05-11 11:06:53 +08001628static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001629{
1630 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1631 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001632#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001633 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1634 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1635 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1636 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1637 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1638 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1639 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001640#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001641};
1642
1643static const unsigned char aes_test_ofb_iv[16] =
1644{
1645 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1646 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1647};
1648
1649static const unsigned char aes_test_ofb_pt[64] =
1650{
1651 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1652 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1653 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1654 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1655 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1656 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1657 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1658 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1659};
1660
Yanray Wang62c99912023-05-11 11:06:53 +08001661static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001662{
1663 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1664 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1665 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1666 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1667 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1668 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1669 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1670 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001671#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001672 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1673 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1674 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1675 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1676 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1677 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1678 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1679 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1680 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1681 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1682 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1683 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1684 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1685 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1686 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1687 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001688#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001689};
1690#endif /* MBEDTLS_CIPHER_MODE_OFB */
1691
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001692#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001693/*
1694 * AES-CTR test vectors from:
1695 *
1696 * http://www.faqs.org/rfcs/rfc3686.html
1697 */
1698
Yanray Wang62c99912023-05-11 11:06:53 +08001699static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001700{
1701 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1702 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1703 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1704 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1705 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1706 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1707};
1708
Yanray Wang62c99912023-05-11 11:06:53 +08001709static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001710{
1711 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1713 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1714 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1715 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1716 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1717};
1718
Yanray Wang62c99912023-05-11 11:06:53 +08001719static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001720{
1721 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1722 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001723 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1724 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1725 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1726 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1727
1728 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1729 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1730 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1731 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1732 0x20, 0x21, 0x22, 0x23 }
1733};
1734
Yanray Wang62c99912023-05-11 11:06:53 +08001735static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001736{
1737 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1738 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1739 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1740 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1741 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1742 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1743 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1744 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1745 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1746 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1747 0x25, 0xB2, 0x07, 0x2F }
1748};
1749
1750static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001751{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001752#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001753
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001754#if defined(MBEDTLS_CIPHER_MODE_XTS)
1755/*
1756 * AES-XTS test vectors from:
1757 *
1758 * IEEE P1619/D16 Annex B
1759 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1760 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1761 */
1762static const unsigned char aes_test_xts_key[][32] =
1763{
1764 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1768 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1769 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1770 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1771 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1772 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1773 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1774 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1775 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1776};
1777
1778static const unsigned char aes_test_xts_pt32[][32] =
1779{
1780 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1784 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1785 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1786 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1787 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1788 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1789 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1790 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1791 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1792};
1793
1794static const unsigned char aes_test_xts_ct32[][32] =
1795{
1796 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1797 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1798 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1799 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1800 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1801 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1802 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1803 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1804 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1805 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1806 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1807 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1808};
1809
1810static const unsigned char aes_test_xts_data_unit[][16] =
1811{
Gilles Peskine449bd832023-01-11 14:50:10 +01001812 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1814 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1816 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001818};
1819
1820#endif /* MBEDTLS_CIPHER_MODE_XTS */
1821
Paul Bakker5121ce52009-01-03 21:22:43 +00001822/*
1823 * Checkup routine
1824 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001825int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001826{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001827 int ret = 0, i, j, u, mode;
1828 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001829 unsigned char key[32];
1830 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001831 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001832#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1833 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001834 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001835#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001836#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001837 unsigned char prv[16];
1838#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001839#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1840 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001841 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001842#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001843#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001844 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001845#endif
1846#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001847 unsigned char nonce_counter[16];
1848 unsigned char stream_block[16];
1849#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001850 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001851
Gilles Peskine449bd832023-01-11 14:50:10 +01001852 memset(key, 0, 32);
1853 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001854
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001855 if (verbose != 0) {
1856#if defined(MBEDTLS_AES_ALT)
1857 mbedtls_printf(" AES note: alternative implementation.\n");
1858#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001859#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001860#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001861 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001862#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001863 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001864#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001865#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001866#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001867 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1868 mbedtls_printf(" AES note: using AESNI.\n");
1869 } else
1870#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001871#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001872 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1873 mbedtls_printf(" AES note: using VIA Padlock.\n");
1874 } else
1875#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001876#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001877 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001878 mbedtls_printf(" AES note: using AESCE.\n");
1879 } else
1880#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001881 {
1882#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1883 mbedtls_printf(" AES note: built-in implementation.\n");
1884#endif
1885 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001886#endif /* MBEDTLS_AES_ALT */
1887 }
1888
Paul Bakker5121ce52009-01-03 21:22:43 +00001889 /*
1890 * ECB mode
1891 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001892 {
1893 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001894 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001895
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001896 for (i = 0; i < num_tests << 1; i++) {
1897 u = i >> 1;
1898 keybits = 128 + u * 64;
1899 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001900
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001901 if (verbose != 0) {
1902 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1903 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1904 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001905#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001906 if (mode == MBEDTLS_AES_DECRYPT) {
1907 if (verbose != 0) {
1908 mbedtls_printf("skipped\n");
1909 }
1910 continue;
1911 }
1912#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001913
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001914 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001915
Yanray Wangb67b4742023-10-31 17:10:32 +08001916#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001917 if (mode == MBEDTLS_AES_DECRYPT) {
1918 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1919 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001920 } else
1921#endif
1922 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001923 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1924 aes_tests = aes_test_ecb_enc[u];
1925 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001926
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001927 /*
1928 * AES-192 is an optional feature that may be unavailable when
1929 * there is an alternative underlying implementation i.e. when
1930 * MBEDTLS_AES_ALT is defined.
1931 */
1932 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1933 mbedtls_printf("skipped\n");
1934 continue;
1935 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001936 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001937 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001938
1939 for (j = 0; j < 10000; j++) {
1940 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1941 if (ret != 0) {
1942 goto exit;
1943 }
1944 }
1945
1946 if (memcmp(buf, aes_tests, 16) != 0) {
1947 ret = 1;
1948 goto exit;
1949 }
1950
1951 if (verbose != 0) {
1952 mbedtls_printf("passed\n");
1953 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001954 }
1955
Gilles Peskine449bd832023-01-11 14:50:10 +01001956 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001957 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001958 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 }
1960
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001961#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001962 /*
1963 * CBC mode
1964 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001965 {
1966 static const int num_tests =
1967 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001968
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001969 for (i = 0; i < num_tests << 1; i++) {
1970 u = i >> 1;
1971 keybits = 128 + u * 64;
1972 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001973
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001974 if (verbose != 0) {
1975 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1976 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001977 }
1978
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001979 memset(iv, 0, 16);
1980 memset(prv, 0, 16);
1981 memset(buf, 0, 16);
1982
1983 if (mode == MBEDTLS_AES_DECRYPT) {
1984 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1985 aes_tests = aes_test_cbc_dec[u];
1986 } else {
1987 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1988 aes_tests = aes_test_cbc_enc[u];
1989 }
1990
1991 /*
1992 * AES-192 is an optional feature that may be unavailable when
1993 * there is an alternative underlying implementation i.e. when
1994 * MBEDTLS_AES_ALT is defined.
1995 */
1996 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1997 mbedtls_printf("skipped\n");
1998 continue;
1999 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002000 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002001 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002002
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002003 for (j = 0; j < 10000; j++) {
2004 if (mode == MBEDTLS_AES_ENCRYPT) {
2005 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002006
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002007 memcpy(tmp, prv, 16);
2008 memcpy(prv, buf, 16);
2009 memcpy(buf, tmp, 16);
2010 }
2011
2012 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2013 if (ret != 0) {
2014 goto exit;
2015 }
2016
2017 }
2018
2019 if (memcmp(buf, aes_tests, 16) != 0) {
2020 ret = 1;
2021 goto exit;
2022 }
2023
2024 if (verbose != 0) {
2025 mbedtls_printf("passed\n");
2026 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002027 }
2028
Gilles Peskine449bd832023-01-11 14:50:10 +01002029 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002030 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002031 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002032 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002033#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002034
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002035#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002036 /*
2037 * CFB128 mode
2038 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002039 {
2040 static const int num_tests =
2041 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002042
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002043 for (i = 0; i < num_tests << 1; i++) {
2044 u = i >> 1;
2045 keybits = 128 + u * 64;
2046 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002047
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002048 if (verbose != 0) {
2049 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2050 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2051 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002052
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002053 memcpy(iv, aes_test_cfb128_iv, 16);
2054 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002055
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002056 offset = 0;
2057 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2058 /*
2059 * AES-192 is an optional feature that may be unavailable when
2060 * there is an alternative underlying implementation i.e. when
2061 * MBEDTLS_AES_ALT is defined.
2062 */
2063 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2064 mbedtls_printf("skipped\n");
2065 continue;
2066 } else if (ret != 0) {
2067 goto exit;
2068 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002069
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002070 if (mode == MBEDTLS_AES_DECRYPT) {
2071 memcpy(buf, aes_test_cfb128_ct[u], 64);
2072 aes_tests = aes_test_cfb128_pt;
2073 } else {
2074 memcpy(buf, aes_test_cfb128_pt, 64);
2075 aes_tests = aes_test_cfb128_ct[u];
2076 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002077
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002078 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2079 if (ret != 0) {
2080 goto exit;
2081 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002082
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002083 if (memcmp(buf, aes_tests, 64) != 0) {
2084 ret = 1;
2085 goto exit;
2086 }
2087
2088 if (verbose != 0) {
2089 mbedtls_printf("passed\n");
2090 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002091 }
2092
Gilles Peskine449bd832023-01-11 14:50:10 +01002093 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002094 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002095 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002096 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002098
Simon Butcherad4e4932018-04-29 00:43:47 +01002099#if defined(MBEDTLS_CIPHER_MODE_OFB)
2100 /*
2101 * OFB mode
2102 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002103 {
2104 static const int num_tests =
2105 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002106
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002107 for (i = 0; i < num_tests << 1; i++) {
2108 u = i >> 1;
2109 keybits = 128 + u * 64;
2110 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002111
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002112 if (verbose != 0) {
2113 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2114 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2115 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002116
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002117 memcpy(iv, aes_test_ofb_iv, 16);
2118 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002119
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002120 offset = 0;
2121 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2122 /*
2123 * AES-192 is an optional feature that may be unavailable when
2124 * there is an alternative underlying implementation i.e. when
2125 * MBEDTLS_AES_ALT is defined.
2126 */
2127 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2128 mbedtls_printf("skipped\n");
2129 continue;
2130 } else if (ret != 0) {
2131 goto exit;
2132 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002133
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002134 if (mode == MBEDTLS_AES_DECRYPT) {
2135 memcpy(buf, aes_test_ofb_ct[u], 64);
2136 aes_tests = aes_test_ofb_pt;
2137 } else {
2138 memcpy(buf, aes_test_ofb_pt, 64);
2139 aes_tests = aes_test_ofb_ct[u];
2140 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002141
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002142 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2143 if (ret != 0) {
2144 goto exit;
2145 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002146
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002147 if (memcmp(buf, aes_tests, 64) != 0) {
2148 ret = 1;
2149 goto exit;
2150 }
2151
2152 if (verbose != 0) {
2153 mbedtls_printf("passed\n");
2154 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002155 }
2156
Gilles Peskine449bd832023-01-11 14:50:10 +01002157 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002158 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002159 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002160 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002161#endif /* MBEDTLS_CIPHER_MODE_OFB */
2162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002163#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002164 /*
2165 * CTR mode
2166 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002167 {
2168 static const int num_tests =
2169 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002170
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002171 for (i = 0; i < num_tests << 1; i++) {
2172 u = i >> 1;
2173 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002174
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002175 if (verbose != 0) {
2176 mbedtls_printf(" AES-CTR-128 (%s): ",
2177 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2178 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002179
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002180 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2181 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002182
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002183 offset = 0;
2184 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2185 goto exit;
2186 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002187
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002188 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002189
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002190 if (mode == MBEDTLS_AES_DECRYPT) {
2191 memcpy(buf, aes_test_ctr_ct[u], len);
2192 aes_tests = aes_test_ctr_pt[u];
2193 } else {
2194 memcpy(buf, aes_test_ctr_pt[u], len);
2195 aes_tests = aes_test_ctr_ct[u];
2196 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002197
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002198 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2199 stream_block, buf, buf);
2200 if (ret != 0) {
2201 goto exit;
2202 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002203
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002204 if (memcmp(buf, aes_tests, len) != 0) {
2205 ret = 1;
2206 goto exit;
2207 }
2208
2209 if (verbose != 0) {
2210 mbedtls_printf("passed\n");
2211 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002212 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002213 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002214
Gilles Peskine449bd832023-01-11 14:50:10 +01002215 if (verbose != 0) {
2216 mbedtls_printf("\n");
2217 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002218#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002219
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002220#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002221 /*
2222 * XTS mode
2223 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002224 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002225 static const int num_tests =
2226 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2227 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002228
Gilles Peskine449bd832023-01-11 14:50:10 +01002229 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002230
Gilles Peskine449bd832023-01-11 14:50:10 +01002231 for (i = 0; i < num_tests << 1; i++) {
2232 const unsigned char *data_unit;
2233 u = i >> 1;
2234 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002235
Gilles Peskine449bd832023-01-11 14:50:10 +01002236 if (verbose != 0) {
2237 mbedtls_printf(" AES-XTS-128 (%s): ",
2238 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2239 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002240
Gilles Peskine449bd832023-01-11 14:50:10 +01002241 memset(key, 0, sizeof(key));
2242 memcpy(key, aes_test_xts_key[u], 32);
2243 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002244
Gilles Peskine449bd832023-01-11 14:50:10 +01002245 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 if (mode == MBEDTLS_AES_DECRYPT) {
2248 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2249 if (ret != 0) {
2250 goto exit;
2251 }
2252 memcpy(buf, aes_test_xts_ct32[u], len);
2253 aes_tests = aes_test_xts_pt32[u];
2254 } else {
2255 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2256 if (ret != 0) {
2257 goto exit;
2258 }
2259 memcpy(buf, aes_test_xts_pt32[u], len);
2260 aes_tests = aes_test_xts_ct32[u];
2261 }
2262
2263
2264 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2265 buf, buf);
2266 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002267 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002268 }
2269
2270 if (memcmp(buf, aes_tests, len) != 0) {
2271 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002272 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002273 }
2274
2275 if (verbose != 0) {
2276 mbedtls_printf("passed\n");
2277 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002278 }
2279
Gilles Peskine449bd832023-01-11 14:50:10 +01002280 if (verbose != 0) {
2281 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002282 }
2283
Gilles Peskine449bd832023-01-11 14:50:10 +01002284 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002285 }
2286#endif /* MBEDTLS_CIPHER_MODE_XTS */
2287
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002288 ret = 0;
2289
2290exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002291 if (ret != 0 && verbose != 0) {
2292 mbedtls_printf("failed\n");
2293 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002294
Gilles Peskine449bd832023-01-11 14:50:10 +01002295 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002296
Gilles Peskine449bd832023-01-11 14:50:10 +01002297 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002298}
2299
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002300#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002302#endif /* MBEDTLS_AES_C */