blob: 940ea0296e819d4c6e2720c0ec01596d58bbfb98 [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)
Yanray Wangb67b4742023-10-31 17:10:32 +08001064#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 if (mode == MBEDTLS_AES_ENCRYPT) {
1066 return mbedtls_internal_aes_encrypt(ctx, input, output);
1067 } else {
1068 return mbedtls_internal_aes_decrypt(ctx, input, output);
1069 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001070#else
1071 return mbedtls_internal_aes_encrypt(ctx, input, output);
Jerry Yu29c91ba2023-08-04 11:02:04 +08001072#endif
Yanray Wang78ee0c92023-05-15 11:23:50 +08001073#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001074}
1075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001077
Paul Bakker5121ce52009-01-03 21:22:43 +00001078/*
1079 * AES-CBC buffer encryption/decryption
1080 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001081int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1082 int mode,
1083 size_t length,
1084 unsigned char iv[16],
1085 const unsigned char *input,
1086 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001087{
Gilles Peskine7820a572021-07-07 21:08:28 +02001088 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001089 unsigned char temp[16];
1090
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001092 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001094
Paul Elliott2ad93672023-08-11 11:07:06 +01001095 /* Nothing to do if length is zero. */
1096 if (length == 0) {
1097 return 0;
1098 }
1099
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 if (length % 16) {
1101 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1102 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001103
Jerry Yu9e628622023-08-17 11:20:09 +08001104#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 if (aes_padlock_ace > 0) {
1106 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1107 return 0;
1108 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001109
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001110 // If padlock data misaligned, we just fall back to
1111 // unaccelerated mode
1112 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001113 }
1114#endif
1115
Dave Rodgman906c63c2023-06-14 17:53:51 +01001116 const unsigned char *ivp = iv;
1117
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 if (mode == MBEDTLS_AES_DECRYPT) {
1119 while (length > 0) {
1120 memcpy(temp, input, 16);
1121 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1122 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001123 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001125 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001126 * the result for the next block in CBC, and the cost of transferring that data from
1127 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001128 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001131
1132 input += 16;
1133 output += 16;
1134 length -= 16;
1135 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 } else {
1137 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001138 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1141 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001142 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001144 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001145
1146 input += 16;
1147 output += 16;
1148 length -= 16;
1149 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001150 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001151 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001152 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001153
Gilles Peskine7820a572021-07-07 21:08:28 +02001154exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001156}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001157#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001158
Aorimn5f778012016-06-09 23:22:58 +02001159#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001160
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001161typedef unsigned char mbedtls_be128[16];
1162
1163/*
1164 * GF(2^128) multiplication function
1165 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001166 * This function multiplies a field element by x in the polynomial field
1167 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001168 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001169 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001170 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001171#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001172MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001173#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001174static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001175 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001176{
1177 uint64_t a, b, ra, rb;
1178
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 a = MBEDTLS_GET_UINT64_LE(x, 0);
1180 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001181
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1183 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001184
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1186 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001187}
1188
Aorimn5f778012016-06-09 23:22:58 +02001189/*
1190 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001191 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001192 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001193 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001194 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001195#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001196MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001197#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001198int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1199 int mode,
1200 size_t length,
1201 const unsigned char data_unit[16],
1202 const unsigned char *input,
1203 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001204{
Janos Follath24eed8d2019-11-22 13:21:35 +00001205 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001206 size_t blocks = length / 16;
1207 size_t leftover = length % 16;
1208 unsigned char tweak[16];
1209 unsigned char prev_tweak[16];
1210 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001213 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001215
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001216 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001218 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 }
Aorimn5f778012016-06-09 23:22:58 +02001220
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001221 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001223 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001224 }
Aorimn5f778012016-06-09 23:22:58 +02001225
Jaeden Amerod82cd862018-04-28 15:02:45 +01001226 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1228 data_unit, tweak);
1229 if (ret != 0) {
1230 return ret;
1231 }
Aorimn5f778012016-06-09 23:22:58 +02001232
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001234 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235 /* We are on the last block in a decrypt operation that has
1236 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001237 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001238 * the leftovers and then update the current tweak for use on this,
1239 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001240 memcpy(prev_tweak, tweak, sizeof(tweak));
1241 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001242 }
1243
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001245
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1247 if (ret != 0) {
1248 return ret;
1249 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001250
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252
1253 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001255
1256 output += 16;
1257 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001258 }
1259
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261 /* If we are on the leftover bytes in a decrypt operation, we need to
1262 * use the previous tweak for these bytes (as saved in prev_tweak). */
1263 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001264
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 /* We are now on the final part of the data unit, which doesn't divide
1266 * evenly by 16. It's time for ciphertext stealing. */
1267 size_t i;
1268 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001269
Jaeden Amerod82cd862018-04-28 15:02:45 +01001270 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001271 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001274 }
Aorimn5f778012016-06-09 23:22:58 +02001275
Dave Rodgman069e7f42022-11-24 19:37:26 +00001276 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001278
Jaeden Amerod82cd862018-04-28 15:02:45 +01001279 /* Copy ciphertext bytes from the previous block for input in this
1280 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001282
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1284 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 }
Aorimn5f778012016-06-09 23:22:58 +02001287
Jaeden Amerod82cd862018-04-28 15:02:45 +01001288 /* Write the result back to the previous block, overriding the previous
1289 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001291 }
1292
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001294}
1295#endif /* MBEDTLS_CIPHER_MODE_XTS */
1296
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001297#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001298/*
1299 * AES-CFB128 buffer encryption/decryption
1300 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001301int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1302 int mode,
1303 size_t length,
1304 size_t *iv_off,
1305 unsigned char iv[16],
1306 const unsigned char *input,
1307 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001308{
Paul Bakker27fdf462011-06-09 13:55:13 +00001309 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001310 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001311 size_t n;
1312
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001314 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001316
1317 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001318
Gilles Peskine449bd832023-01-11 14:50:10 +01001319 if (n > 15) {
1320 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1321 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001322
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 if (mode == MBEDTLS_AES_DECRYPT) {
1324 while (length--) {
1325 if (n == 0) {
1326 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1327 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001328 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001330 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001331
1332 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001334 iv[n] = (unsigned char) c;
1335
Gilles Peskine449bd832023-01-11 14:50:10 +01001336 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001337 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 } else {
1339 while (length--) {
1340 if (n == 0) {
1341 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1342 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001343 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001344 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001345 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001346
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 }
1351 }
1352
1353 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001354 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001355
Gilles Peskine7820a572021-07-07 21:08:28 +02001356exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001357 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001358}
Paul Bakker556efba2014-01-24 15:38:12 +01001359
1360/*
1361 * AES-CFB8 buffer encryption/decryption
1362 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001363int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1364 int mode,
1365 size_t length,
1366 unsigned char iv[16],
1367 const unsigned char *input,
1368 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001369{
Gilles Peskine7820a572021-07-07 21:08:28 +02001370 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001371 unsigned char c;
1372 unsigned char ov[17];
1373
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001375 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 }
1377 while (length--) {
1378 memcpy(ov, iv, 16);
1379 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1380 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001381 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 }
Paul Bakker556efba2014-01-24 15:38:12 +01001383
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001385 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 }
Paul Bakker556efba2014-01-24 15:38:12 +01001387
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001389
Gilles Peskine449bd832023-01-11 14:50:10 +01001390 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001391 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 }
Paul Bakker556efba2014-01-24 15:38:12 +01001393
Gilles Peskine449bd832023-01-11 14:50:10 +01001394 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001395 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001396 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001397
Gilles Peskine7820a572021-07-07 21:08:28 +02001398exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001399 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001400}
Simon Butcher76a5b222018-04-22 22:57:27 +01001401#endif /* MBEDTLS_CIPHER_MODE_CFB */
1402
1403#if defined(MBEDTLS_CIPHER_MODE_OFB)
1404/*
1405 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1406 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001407int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1408 size_t length,
1409 size_t *iv_off,
1410 unsigned char iv[16],
1411 const unsigned char *input,
1412 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001413{
Simon Butcherad4e4932018-04-29 00:43:47 +01001414 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001415 size_t n;
1416
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001417 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001418
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 if (n > 15) {
1420 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1421 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001422
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 while (length--) {
1424 if (n == 0) {
1425 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1426 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001427 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001428 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001429 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001430 *output++ = *input++ ^ iv[n];
1431
Gilles Peskine449bd832023-01-11 14:50:10 +01001432 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001433 }
1434
1435 *iv_off = n;
1436
Simon Butcherad4e4932018-04-29 00:43:47 +01001437exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001438 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001439}
1440#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001443/*
1444 * AES-CTR buffer encryption/decryption
1445 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001446int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1447 size_t length,
1448 size_t *nc_off,
1449 unsigned char nonce_counter[16],
1450 unsigned char stream_block[16],
1451 const unsigned char *input,
1452 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001453{
Paul Bakker369e14b2012-04-18 14:16:09 +00001454 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001455 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001456 size_t n;
1457
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001458 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001459
Gilles Peskine449bd832023-01-11 14:50:10 +01001460 if (n > 0x0F) {
1461 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1462 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001463
Gilles Peskine449bd832023-01-11 14:50:10 +01001464 while (length--) {
1465 if (n == 0) {
1466 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1467 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001468 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001469 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001470
Gilles Peskine449bd832023-01-11 14:50:10 +01001471 for (i = 16; i > 0; i--) {
1472 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001473 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001474 }
1475 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001476 }
1477 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001478 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001479
Gilles Peskine449bd832023-01-11 14:50:10 +01001480 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001481 }
1482
1483 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001484 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001485
Gilles Peskine7820a572021-07-07 21:08:28 +02001486exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001487 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001488}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001494/*
1495 * AES test vectors from:
1496 *
1497 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1498 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001499#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001500static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001501{
1502 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1503 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001504#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001505 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1506 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1507 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1508 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001509#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001510};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001511#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001512
Yanray Wang62c99912023-05-11 11:06:53 +08001513static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001514{
1515 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1516 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001517#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001518 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1519 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1520 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1521 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001522#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001523};
1524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001526static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001527{
1528 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1529 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001530#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001531 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1532 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1533 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1534 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001535#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001536};
1537
Yanray Wang62c99912023-05-11 11:06:53 +08001538static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001539{
1540 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1541 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001542#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001543 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1544 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1545 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1546 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001547#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001548};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001549#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001550
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001551#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001552/*
1553 * AES-CFB128 test vectors from:
1554 *
1555 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1556 */
Yanray Wang62c99912023-05-11 11:06:53 +08001557static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001558{
1559 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1560 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001561#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001562 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1563 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1564 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1565 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1566 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1567 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1568 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001569#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001570};
1571
1572static const unsigned char aes_test_cfb128_iv[16] =
1573{
1574 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1575 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1576};
1577
1578static const unsigned char aes_test_cfb128_pt[64] =
1579{
1580 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1581 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1582 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1583 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1584 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1585 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1586 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1587 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1588};
1589
Yanray Wang62c99912023-05-11 11:06:53 +08001590static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001591{
1592 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1593 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1594 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1595 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1596 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1597 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1598 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1599 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001600#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001601 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1602 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1603 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1604 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1605 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1606 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1607 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1608 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1609 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1610 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1611 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1612 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1613 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1614 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1615 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1616 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001617#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001618};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001619#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001620
Simon Butcherad4e4932018-04-29 00:43:47 +01001621#if defined(MBEDTLS_CIPHER_MODE_OFB)
1622/*
1623 * AES-OFB test vectors from:
1624 *
Simon Butcher5db13622018-06-04 22:11:25 +01001625 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001626 */
Yanray Wang62c99912023-05-11 11:06:53 +08001627static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001628{
1629 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1630 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001631#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001632 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1633 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1634 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1635 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1636 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1637 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1638 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001639#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001640};
1641
1642static const unsigned char aes_test_ofb_iv[16] =
1643{
1644 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1645 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1646};
1647
1648static const unsigned char aes_test_ofb_pt[64] =
1649{
1650 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1651 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1652 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1653 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1654 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1655 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1656 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1657 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1658};
1659
Yanray Wang62c99912023-05-11 11:06:53 +08001660static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001661{
1662 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1663 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1664 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1665 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1666 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1667 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1668 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1669 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001670#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001671 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1672 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1673 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1674 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1675 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1676 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1677 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1678 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1679 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1680 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1681 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1682 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1683 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1684 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1685 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1686 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001687#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001688};
1689#endif /* MBEDTLS_CIPHER_MODE_OFB */
1690
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001691#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001692/*
1693 * AES-CTR test vectors from:
1694 *
1695 * http://www.faqs.org/rfcs/rfc3686.html
1696 */
1697
Yanray Wang62c99912023-05-11 11:06:53 +08001698static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001699{
1700 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1701 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1702 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1703 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1704 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1705 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1706};
1707
Yanray Wang62c99912023-05-11 11:06:53 +08001708static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001709{
1710 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1712 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1713 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1714 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1715 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1716};
1717
Yanray Wang62c99912023-05-11 11:06:53 +08001718static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001719{
1720 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1721 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001722 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1723 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1724 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1725 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1726
1727 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1728 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1729 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1730 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1731 0x20, 0x21, 0x22, 0x23 }
1732};
1733
Yanray Wang62c99912023-05-11 11:06:53 +08001734static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001735{
1736 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1737 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1738 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1739 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1740 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1741 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1742 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1743 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1744 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1745 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1746 0x25, 0xB2, 0x07, 0x2F }
1747};
1748
1749static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001750{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001751#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001752
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001753#if defined(MBEDTLS_CIPHER_MODE_XTS)
1754/*
1755 * AES-XTS test vectors from:
1756 *
1757 * IEEE P1619/D16 Annex B
1758 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1759 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1760 */
1761static const unsigned char aes_test_xts_key[][32] =
1762{
1763 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1768 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1769 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1770 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1771 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1772 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1773 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1774 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1775};
1776
1777static const unsigned char aes_test_xts_pt32[][32] =
1778{
1779 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
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};
1792
1793static const unsigned char aes_test_xts_ct32[][32] =
1794{
1795 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1796 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1797 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1798 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1799 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1800 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1801 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1802 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1803 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1804 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1805 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1806 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1807};
1808
1809static const unsigned char aes_test_xts_data_unit[][16] =
1810{
Gilles Peskine449bd832023-01-11 14:50:10 +01001811 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1813 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1815 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001817};
1818
1819#endif /* MBEDTLS_CIPHER_MODE_XTS */
1820
Paul Bakker5121ce52009-01-03 21:22:43 +00001821/*
1822 * Checkup routine
1823 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001824int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001825{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001826 int ret = 0, i, j, u, mode;
1827 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001828 unsigned char key[32];
1829 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001830 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001831#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1832 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001834#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001835#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001836 unsigned char prv[16];
1837#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001838#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1839 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001840 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001841#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001842#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001843 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001844#endif
1845#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001846 unsigned char nonce_counter[16];
1847 unsigned char stream_block[16];
1848#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001850
Gilles Peskine449bd832023-01-11 14:50:10 +01001851 memset(key, 0, 32);
1852 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001853
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001854 if (verbose != 0) {
1855#if defined(MBEDTLS_AES_ALT)
1856 mbedtls_printf(" AES note: alternative implementation.\n");
1857#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001858#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001859#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001860 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001861#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001862 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001863#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001864#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001865#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001866 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1867 mbedtls_printf(" AES note: using AESNI.\n");
1868 } else
1869#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001870#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001871 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1872 mbedtls_printf(" AES note: using VIA Padlock.\n");
1873 } else
1874#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001875#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001876 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001877 mbedtls_printf(" AES note: using AESCE.\n");
1878 } else
1879#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001880 {
1881#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1882 mbedtls_printf(" AES note: built-in implementation.\n");
1883#endif
1884 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001885#endif /* MBEDTLS_AES_ALT */
1886 }
1887
Paul Bakker5121ce52009-01-03 21:22:43 +00001888 /*
1889 * ECB mode
1890 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001891 {
1892 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001893 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001894
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001895 for (i = 0; i < num_tests << 1; i++) {
1896 u = i >> 1;
1897 keybits = 128 + u * 64;
1898 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001899
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001900 if (verbose != 0) {
1901 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1902 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1903 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001904#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001905 if (mode == MBEDTLS_AES_DECRYPT) {
1906 if (verbose != 0) {
1907 mbedtls_printf("skipped\n");
1908 }
1909 continue;
1910 }
1911#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001912
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001913 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001914
Yanray Wangb67b4742023-10-31 17:10:32 +08001915#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001916 if (mode == MBEDTLS_AES_DECRYPT) {
1917 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1918 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001919 } else
1920#endif
1921 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001922 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1923 aes_tests = aes_test_ecb_enc[u];
1924 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001925
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001926 /*
1927 * AES-192 is an optional feature that may be unavailable when
1928 * there is an alternative underlying implementation i.e. when
1929 * MBEDTLS_AES_ALT is defined.
1930 */
1931 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1932 mbedtls_printf("skipped\n");
1933 continue;
1934 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001935 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001936 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001937
1938 for (j = 0; j < 10000; j++) {
1939 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1940 if (ret != 0) {
1941 goto exit;
1942 }
1943 }
1944
1945 if (memcmp(buf, aes_tests, 16) != 0) {
1946 ret = 1;
1947 goto exit;
1948 }
1949
1950 if (verbose != 0) {
1951 mbedtls_printf("passed\n");
1952 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001953 }
1954
Gilles Peskine449bd832023-01-11 14:50:10 +01001955 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001956 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001957 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001958 }
1959
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001960#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001961 /*
1962 * CBC mode
1963 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001964 {
1965 static const int num_tests =
1966 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001967
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001968 for (i = 0; i < num_tests << 1; i++) {
1969 u = i >> 1;
1970 keybits = 128 + u * 64;
1971 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001972
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001973 if (verbose != 0) {
1974 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1975 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001976 }
1977
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001978 memset(iv, 0, 16);
1979 memset(prv, 0, 16);
1980 memset(buf, 0, 16);
1981
1982 if (mode == MBEDTLS_AES_DECRYPT) {
1983 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1984 aes_tests = aes_test_cbc_dec[u];
1985 } else {
1986 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1987 aes_tests = aes_test_cbc_enc[u];
1988 }
1989
1990 /*
1991 * AES-192 is an optional feature that may be unavailable when
1992 * there is an alternative underlying implementation i.e. when
1993 * MBEDTLS_AES_ALT is defined.
1994 */
1995 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1996 mbedtls_printf("skipped\n");
1997 continue;
1998 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001999 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002000 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002001
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002002 for (j = 0; j < 10000; j++) {
2003 if (mode == MBEDTLS_AES_ENCRYPT) {
2004 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002005
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002006 memcpy(tmp, prv, 16);
2007 memcpy(prv, buf, 16);
2008 memcpy(buf, tmp, 16);
2009 }
2010
2011 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2012 if (ret != 0) {
2013 goto exit;
2014 }
2015
2016 }
2017
2018 if (memcmp(buf, aes_tests, 16) != 0) {
2019 ret = 1;
2020 goto exit;
2021 }
2022
2023 if (verbose != 0) {
2024 mbedtls_printf("passed\n");
2025 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002026 }
2027
Gilles Peskine449bd832023-01-11 14:50:10 +01002028 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002029 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002030 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002031 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002032#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002034#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002035 /*
2036 * CFB128 mode
2037 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002038 {
2039 static const int num_tests =
2040 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002041
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002042 for (i = 0; i < num_tests << 1; i++) {
2043 u = i >> 1;
2044 keybits = 128 + u * 64;
2045 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002046
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002047 if (verbose != 0) {
2048 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2049 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2050 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002051
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002052 memcpy(iv, aes_test_cfb128_iv, 16);
2053 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002054
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002055 offset = 0;
2056 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2057 /*
2058 * AES-192 is an optional feature that may be unavailable when
2059 * there is an alternative underlying implementation i.e. when
2060 * MBEDTLS_AES_ALT is defined.
2061 */
2062 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2063 mbedtls_printf("skipped\n");
2064 continue;
2065 } else if (ret != 0) {
2066 goto exit;
2067 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002068
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002069 if (mode == MBEDTLS_AES_DECRYPT) {
2070 memcpy(buf, aes_test_cfb128_ct[u], 64);
2071 aes_tests = aes_test_cfb128_pt;
2072 } else {
2073 memcpy(buf, aes_test_cfb128_pt, 64);
2074 aes_tests = aes_test_cfb128_ct[u];
2075 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002076
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002077 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2078 if (ret != 0) {
2079 goto exit;
2080 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002081
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002082 if (memcmp(buf, aes_tests, 64) != 0) {
2083 ret = 1;
2084 goto exit;
2085 }
2086
2087 if (verbose != 0) {
2088 mbedtls_printf("passed\n");
2089 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002090 }
2091
Gilles Peskine449bd832023-01-11 14:50:10 +01002092 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002093 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002094 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002095 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002096#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002097
Simon Butcherad4e4932018-04-29 00:43:47 +01002098#if defined(MBEDTLS_CIPHER_MODE_OFB)
2099 /*
2100 * OFB mode
2101 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002102 {
2103 static const int num_tests =
2104 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002105
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002106 for (i = 0; i < num_tests << 1; i++) {
2107 u = i >> 1;
2108 keybits = 128 + u * 64;
2109 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002110
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002111 if (verbose != 0) {
2112 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2113 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2114 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002115
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002116 memcpy(iv, aes_test_ofb_iv, 16);
2117 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002118
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002119 offset = 0;
2120 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2121 /*
2122 * AES-192 is an optional feature that may be unavailable when
2123 * there is an alternative underlying implementation i.e. when
2124 * MBEDTLS_AES_ALT is defined.
2125 */
2126 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2127 mbedtls_printf("skipped\n");
2128 continue;
2129 } else if (ret != 0) {
2130 goto exit;
2131 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002132
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002133 if (mode == MBEDTLS_AES_DECRYPT) {
2134 memcpy(buf, aes_test_ofb_ct[u], 64);
2135 aes_tests = aes_test_ofb_pt;
2136 } else {
2137 memcpy(buf, aes_test_ofb_pt, 64);
2138 aes_tests = aes_test_ofb_ct[u];
2139 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002140
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002141 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2142 if (ret != 0) {
2143 goto exit;
2144 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002145
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002146 if (memcmp(buf, aes_tests, 64) != 0) {
2147 ret = 1;
2148 goto exit;
2149 }
2150
2151 if (verbose != 0) {
2152 mbedtls_printf("passed\n");
2153 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002154 }
2155
Gilles Peskine449bd832023-01-11 14:50:10 +01002156 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002157 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002158 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002159 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002160#endif /* MBEDTLS_CIPHER_MODE_OFB */
2161
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002162#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002163 /*
2164 * CTR mode
2165 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002166 {
2167 static const int num_tests =
2168 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002169
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002170 for (i = 0; i < num_tests << 1; i++) {
2171 u = i >> 1;
2172 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002173
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002174 if (verbose != 0) {
2175 mbedtls_printf(" AES-CTR-128 (%s): ",
2176 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2177 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002178
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002179 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2180 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002181
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002182 offset = 0;
2183 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2184 goto exit;
2185 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002186
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002187 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002188
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002189 if (mode == MBEDTLS_AES_DECRYPT) {
2190 memcpy(buf, aes_test_ctr_ct[u], len);
2191 aes_tests = aes_test_ctr_pt[u];
2192 } else {
2193 memcpy(buf, aes_test_ctr_pt[u], len);
2194 aes_tests = aes_test_ctr_ct[u];
2195 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002196
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002197 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2198 stream_block, buf, buf);
2199 if (ret != 0) {
2200 goto exit;
2201 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002202
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002203 if (memcmp(buf, aes_tests, len) != 0) {
2204 ret = 1;
2205 goto exit;
2206 }
2207
2208 if (verbose != 0) {
2209 mbedtls_printf("passed\n");
2210 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002211 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002212 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002213
Gilles Peskine449bd832023-01-11 14:50:10 +01002214 if (verbose != 0) {
2215 mbedtls_printf("\n");
2216 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002217#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002218
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002219#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002220 /*
2221 * XTS mode
2222 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002223 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002224 static const int num_tests =
2225 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2226 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002227
Gilles Peskine449bd832023-01-11 14:50:10 +01002228 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002229
Gilles Peskine449bd832023-01-11 14:50:10 +01002230 for (i = 0; i < num_tests << 1; i++) {
2231 const unsigned char *data_unit;
2232 u = i >> 1;
2233 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002234
Gilles Peskine449bd832023-01-11 14:50:10 +01002235 if (verbose != 0) {
2236 mbedtls_printf(" AES-XTS-128 (%s): ",
2237 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2238 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002239
Gilles Peskine449bd832023-01-11 14:50:10 +01002240 memset(key, 0, sizeof(key));
2241 memcpy(key, aes_test_xts_key[u], 32);
2242 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002243
Gilles Peskine449bd832023-01-11 14:50:10 +01002244 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002245
Gilles Peskine449bd832023-01-11 14:50:10 +01002246 if (mode == MBEDTLS_AES_DECRYPT) {
2247 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2248 if (ret != 0) {
2249 goto exit;
2250 }
2251 memcpy(buf, aes_test_xts_ct32[u], len);
2252 aes_tests = aes_test_xts_pt32[u];
2253 } else {
2254 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2255 if (ret != 0) {
2256 goto exit;
2257 }
2258 memcpy(buf, aes_test_xts_pt32[u], len);
2259 aes_tests = aes_test_xts_ct32[u];
2260 }
2261
2262
2263 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2264 buf, buf);
2265 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002266 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002267 }
2268
2269 if (memcmp(buf, aes_tests, len) != 0) {
2270 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002271 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002272 }
2273
2274 if (verbose != 0) {
2275 mbedtls_printf("passed\n");
2276 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002277 }
2278
Gilles Peskine449bd832023-01-11 14:50:10 +01002279 if (verbose != 0) {
2280 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002281 }
2282
Gilles Peskine449bd832023-01-11 14:50:10 +01002283 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002284 }
2285#endif /* MBEDTLS_CIPHER_MODE_XTS */
2286
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002287 ret = 0;
2288
2289exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002290 if (ret != 0 && verbose != 0) {
2291 mbedtls_printf("failed\n");
2292 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002293
Gilles Peskine449bd832023-01-11 14:50:10 +01002294 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002295
Gilles Peskine449bd832023-01-11 14:50:10 +01002296 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002297}
2298
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002299#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002300
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002301#endif /* MBEDTLS_AES_C */