blob: e6b071a900b57347be1ce461d91e5bed9ac200d2 [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020070
Jerry Yu9e628622023-08-17 11:20:09 +080071#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000072static int aes_padlock_ace = -1;
73#endif
74
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000076/*
77 * Forward S-box
78 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010079#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
80 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000081static const unsigned char FSb[256] =
82{
83 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
84 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
85 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
86 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
87 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
88 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
89 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
90 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
91 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
92 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
93 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
94 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
95 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
96 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
97 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
98 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
99 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
100 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
101 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
102 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
103 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
104 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
105 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
106 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
107 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
108 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
109 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
110 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
111 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
112 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
113 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
114 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
115};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100116#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
117 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000118
119/*
120 * Forward tables
121 */
122#define FT \
123\
Gilles Peskine449bd832023-01-11 14:50:10 +0100124 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
125 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
126 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
127 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
128 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
129 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
130 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
131 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
132 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
133 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
134 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
135 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
136 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
137 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
138 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
139 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
140 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
141 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
142 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
143 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
144 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
145 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
146 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
147 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
148 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
149 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
150 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
151 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
152 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
153 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
154 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
155 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
156 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
157 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
158 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
159 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
160 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
161 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
162 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
163 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
164 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
165 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
166 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
167 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
168 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
169 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
170 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
171 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
172 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
173 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
174 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
175 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
176 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
177 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
178 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
179 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
180 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
181 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
182 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
183 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
184 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
185 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
186 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
187 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 +0000188
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100189#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100190#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000191static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000192#undef V
193
Hanno Beckerad049a92017-06-19 16:31:54 +0100194#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000197static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000198#undef V
199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000201static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000202#undef V
203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000205static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000206#undef V
207
Hanno Becker177d3cf2017-06-07 15:52:48 +0100208#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200209
Dave Rodgman1be24632023-06-29 12:01:24 +0100210#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
211
Paul Bakker5121ce52009-01-03 21:22:43 +0000212#undef FT
213
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100214#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000215/*
216 * Reverse S-box
217 */
218static const unsigned char RSb[256] =
219{
220 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
221 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
222 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
223 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
224 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
225 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
226 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
227 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
228 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
229 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
230 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
231 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
232 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
233 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
234 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
235 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
236 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
237 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
238 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
239 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
240 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
241 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
242 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
243 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
244 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
245 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
246 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
247 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
248 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
249 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
250 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
251 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
252};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100253#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255/*
256 * Reverse tables
257 */
258#define RT \
259\
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
261 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
262 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
263 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
264 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
265 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
266 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
267 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
268 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
269 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
270 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
271 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
272 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
273 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
274 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
275 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
276 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
277 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
278 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
279 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
280 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
281 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
282 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
283 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
284 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
285 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
286 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
287 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
288 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
289 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
290 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
291 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
292 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
293 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
294 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
295 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
296 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
297 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
298 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
299 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
300 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
301 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
302 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
303 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
304 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
305 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
306 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
307 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
308 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
309 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
310 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
311 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
312 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
313 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
314 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
315 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
316 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
317 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
318 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
319 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
320 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
321 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
322 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
323 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 +0000324
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100325#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
326
Gilles Peskine449bd832023-01-11 14:50:10 +0100327#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000328static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000329#undef V
330
Hanno Beckerad049a92017-06-19 16:31:54 +0100331#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000335#undef V
336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000338static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000339#undef V
340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000342static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000343#undef V
344
Hanno Becker177d3cf2017-06-07 15:52:48 +0100345#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200346
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800347#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
348
Paul Bakker5121ce52009-01-03 21:22:43 +0000349#undef RT
350
Dave Rodgman34152a42023-06-27 18:31:24 +0100351#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000352/*
353 * Round constants
354 */
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200355static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000356{
357 0x00000001, 0x00000002, 0x00000004, 0x00000008,
358 0x00000010, 0x00000020, 0x00000040, 0x00000080,
359 0x0000001B, 0x00000036
360};
Dave Rodgman34152a42023-06-27 18:31:24 +0100361#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
365/*
366 * Forward S-box & tables
367 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100368#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
369 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000370static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100371#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
372 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100373#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200374static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100375#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200376static uint32_t FT1[256];
377static uint32_t FT2[256];
378static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100379#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100380#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
382/*
383 * Reverse S-box & tables
384 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100385#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000386static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100387#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100388
389#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000390static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100391#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000392static uint32_t RT1[256];
393static uint32_t RT2[256];
394static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100395#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100396#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Dave Rodgman8c753f92023-06-27 18:16:13 +0100398#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000399/*
400 * Round constants
401 */
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200402static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
404/*
405 * Tables generation code
406 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100407#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
408#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
409#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
411static int aes_init_done = 0;
412
Gilles Peskine449bd832023-01-11 14:50:10 +0100413static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000414{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800415 int i;
416 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800417 uint8_t pow[256];
418 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420 /*
421 * compute pow and log tables over GF(2^8)
422 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800425 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800426 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 }
428
429 /*
430 * calculate the round constants
431 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200433 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800434 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000435 }
436
437 /*
438 * generate the forward and reverse S-boxes
439 */
440 FSb[0x00] = 0x63;
441 RSb[0x63] = 0x00;
442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 x = pow[255 - log[i]];
445
Yanray Wangfe944ce2023-06-26 18:16:01 +0800446 y = x; y = (y << 1) | (y >> 7);
447 x ^= y; y = (y << 1) | (y >> 7);
448 x ^= y; y = (y << 1) | (y >> 7);
449 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 x ^= y ^ 0x63;
451
Yanray Wangfe944ce2023-06-26 18:16:01 +0800452 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 RSb[x] = (unsigned char) i;
454 }
455
456 /*
457 * generate the forward and reverse tables
458 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000460 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800461 y = XTIME(x);
462 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464 FT0[i] = ((uint32_t) y) ^
465 ((uint32_t) x << 8) ^
466 ((uint32_t) x << 16) ^
467 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
Hanno Beckerad049a92017-06-19 16:31:54 +0100469#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 FT1[i] = ROTL8(FT0[i]);
471 FT2[i] = ROTL8(FT1[i]);
472 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100473#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
475 x = RSb[i];
476
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100477#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
479 ((uint32_t) MUL(0x09, x) << 8) ^
480 ((uint32_t) MUL(0x0D, x) << 16) ^
481 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Hanno Beckerad049a92017-06-19 16:31:54 +0100483#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 RT1[i] = ROTL8(RT0[i]);
485 RT2[i] = ROTL8(RT1[i]);
486 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100487#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100488#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000489 }
490}
491
Dave Rodgman8c753f92023-06-27 18:16:13 +0100492#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
493
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200494#undef ROTL8
495
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000497
Hanno Beckerad049a92017-06-19 16:31:54 +0100498#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
501#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
502#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200503
504#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100505#define AES_RT1(idx) ROTL8(RT0[idx])
506#define AES_RT2(idx) ROTL16(RT0[idx])
507#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200508
509#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100510#define AES_FT1(idx) ROTL8(FT0[idx])
511#define AES_FT2(idx) ROTL16(FT0[idx])
512#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200513
Hanno Becker177d3cf2017-06-07 15:52:48 +0100514#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200515
516#define AES_RT0(idx) RT0[idx]
517#define AES_RT1(idx) RT1[idx]
518#define AES_RT2(idx) RT2[idx]
519#define AES_RT3(idx) RT3[idx]
520
521#define AES_FT0(idx) FT0[idx]
522#define AES_FT1(idx) FT1[idx]
523#define AES_FT2(idx) FT2[idx]
524#define AES_FT3(idx) FT3[idx]
525
Hanno Becker177d3cf2017-06-07 15:52:48 +0100526#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200529{
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200531}
532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200534{
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200536 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200540}
541
Jaeden Amero9366feb2018-05-29 18:55:17 +0100542#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100543void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100544{
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 mbedtls_aes_init(&ctx->crypt);
546 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100547}
548
Gilles Peskine449bd832023-01-11 14:50:10 +0100549void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100550{
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100552 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 }
Simon Butcher5201e412018-12-06 17:40:14 +0000554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 mbedtls_aes_free(&ctx->crypt);
556 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100557}
558#endif /* MBEDTLS_CIPHER_MODE_XTS */
559
Gilles Peskine0de8f852023-03-16 17:14:59 +0100560/* Some implementations need the round keys to be aligned.
561 * Return an offset to be added to buf, such that (buf + offset) is
562 * correctly aligned.
563 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
564 * i.e. an offset of 1 means 4 bytes and so on.
565 */
Jerry Yu96084472023-08-17 18:10:45 +0800566#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100567 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100568#define MAY_NEED_TO_ALIGN
569#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100570
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100571#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
572 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100573static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
574{
575#if defined(MAY_NEED_TO_ALIGN)
576 int align_16_bytes = 0;
577
Jerry Yu9e628622023-08-17 11:20:09 +0800578#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100579 if (aes_padlock_ace == -1) {
580 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
581 }
582 if (aes_padlock_ace) {
583 align_16_bytes = 1;
584 }
585#endif
586
Gilles Peskine9c682e72023-03-16 17:21:33 +0100587#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100588 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
589 align_16_bytes = 1;
590 }
591#endif
592
593 if (align_16_bytes) {
594 /* These implementations needs 16-byte alignment
595 * for the round key array. */
596 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
597 if (delta == 0) {
598 return 0;
599 } else {
600 return 4 - delta; // 16 bytes = 4 uint32_t
601 }
602 }
603#else /* MAY_NEED_TO_ALIGN */
604 (void) buf;
605#endif /* MAY_NEED_TO_ALIGN */
606
607 return 0;
608}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100609#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
610 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100611
Paul Bakker5121ce52009-01-03 21:22:43 +0000612/*
613 * AES key schedule (encryption)
614 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200615#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100616int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
617 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000618{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000619 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000620
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000622 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800623#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 case 192: ctx->nr = 12; break;
625 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800626#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 }
629
Simon Butcher5201e412018-12-06 17:40:14 +0000630#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000632 aes_gen_tables();
633 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000634 }
635#endif
636
Gilles Peskine0de8f852023-03-16 17:14:59 +0100637 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100638 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100640#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
642 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
643 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100644#endif
645
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800646#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100647 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800648 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
649 }
650#endif
651
Jerry Yu29c91ba2023-08-04 11:02:04 +0800652#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800653 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000655 }
656
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000658 case 10:
659
Jerry Yu3a0f0442023-08-17 17:06:21 +0800660 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200661 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
663 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
664 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
665 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
667 RK[5] = RK[1] ^ RK[4];
668 RK[6] = RK[2] ^ RK[5];
669 RK[7] = RK[3] ^ RK[6];
670 }
671 break;
672
Arto Kinnunen732ca322023-04-14 14:26:10 +0800673#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 case 12:
675
Jerry Yu3a0f0442023-08-17 17:06:21 +0800676 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200677 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
679 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
680 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
681 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
683 RK[7] = RK[1] ^ RK[6];
684 RK[8] = RK[2] ^ RK[7];
685 RK[9] = RK[3] ^ RK[8];
686 RK[10] = RK[4] ^ RK[9];
687 RK[11] = RK[5] ^ RK[10];
688 }
689 break;
690
691 case 14:
692
Jerry Yu3a0f0442023-08-17 17:06:21 +0800693 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200694 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
696 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
697 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
698 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000699
700 RK[9] = RK[1] ^ RK[8];
701 RK[10] = RK[2] ^ RK[9];
702 RK[11] = RK[3] ^ RK[10];
703
704 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
706 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
707 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
708 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
710 RK[13] = RK[5] ^ RK[12];
711 RK[14] = RK[6] ^ RK[13];
712 RK[15] = RK[7] ^ RK[14];
713 }
714 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800715#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800719#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000720}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200721#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
723/*
724 * AES key schedule (decryption)
725 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200726#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100727int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
728 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000729{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800730#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800731 uint32_t *SK;
732#endif
733 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200734 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000735 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800736
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200737
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
Gilles Peskine0de8f852023-03-16 17:14:59 +0100740 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100741 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000742
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200743 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200745 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000747
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200748 ctx->nr = cty.nr;
749
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100750#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
752 mbedtls_aesni_inverse_key((unsigned char *) RK,
753 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200754 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100755 }
756#endif
757
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800758#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100759 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800760 mbedtls_aesce_inverse_key(
761 (unsigned char *) RK,
762 (const unsigned char *) (cty.buf + cty.rk_offset),
763 ctx->nr);
764 goto exit;
765 }
766#endif
767
Jerry Yu29c91ba2023-08-04 11:02:04 +0800768#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100769 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000770
771 *RK++ = *SK++;
772 *RK++ = *SK++;
773 *RK++ = *SK++;
774 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800775 SK -= 8;
776 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
777 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
779 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
780 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
781 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000782 }
783 }
784
785 *RK++ = *SK++;
786 *RK++ = *SK++;
787 *RK++ = *SK++;
788 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800789#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200790exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000792
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000794}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100795#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100796
797#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100798static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
799 unsigned int keybits,
800 const unsigned char **key1,
801 unsigned int *key1bits,
802 const unsigned char **key2,
803 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100804{
805 const unsigned int half_keybits = keybits / 2;
806 const unsigned int half_keybytes = half_keybits / 8;
807
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100809 case 256: break;
810 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100812 }
813
814 *key1bits = half_keybits;
815 *key2bits = half_keybits;
816 *key1 = &key[0];
817 *key2 = &key[half_keybytes];
818
819 return 0;
820}
821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
823 const unsigned char *key,
824 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100825{
Janos Follath24eed8d2019-11-22 13:21:35 +0000826 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100827 const unsigned char *key1, *key2;
828 unsigned int key1bits, key2bits;
829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
831 &key2, &key2bits);
832 if (ret != 0) {
833 return ret;
834 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100835
836 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
838 if (ret != 0) {
839 return ret;
840 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100841
842 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100844}
845
Gilles Peskine449bd832023-01-11 14:50:10 +0100846int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
847 const unsigned char *key,
848 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100849{
Janos Follath24eed8d2019-11-22 13:21:35 +0000850 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100851 const unsigned char *key1, *key2;
852 unsigned int key1bits, key2bits;
853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
855 &key2, &key2bits);
856 if (ret != 0) {
857 return ret;
858 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100859
860 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
862 if (ret != 0) {
863 return ret;
864 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100865
866 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100868}
869#endif /* MBEDTLS_CIPHER_MODE_XTS */
870
Gilles Peskine449bd832023-01-11 14:50:10 +0100871#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100872 do \
873 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
875 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
876 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
877 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100878 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
880 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
881 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
882 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100883 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
885 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
886 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
887 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100888 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
890 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
891 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
892 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
893 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000894
Gilles Peskine449bd832023-01-11 14:50:10 +0100895#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100896 do \
897 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
899 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
900 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
901 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100902 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
904 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
905 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
906 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100907 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
909 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
910 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
911 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100912 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
914 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
915 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
916 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
917 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000918
919/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200920 * AES-ECB block encryption
921 */
922#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100923int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
924 const unsigned char input[16],
925 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200926{
927 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100928 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200930 uint32_t X[4];
931 uint32_t Y[4];
932 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
935 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
936 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
937 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200938
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
940 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]);
941 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 +0200942 }
943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 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 +0200945
Gilles Peskine5197c662020-08-26 17:03:24 +0200946 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
948 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
949 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
950 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200951
Gilles Peskine5197c662020-08-26 17:03:24 +0200952 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
954 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
955 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
956 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200957
Gilles Peskine5197c662020-08-26 17:03:24 +0200958 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
960 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
961 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200963
Gilles Peskine5197c662020-08-26 17:03:24 +0200964 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
966 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
967 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
971 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
972 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
973 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200978}
979#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
980
981/*
982 * AES-ECB block decryption
983 */
984#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100985int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
986 const unsigned char input[16],
987 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200988{
989 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100990 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200992 uint32_t X[4];
993 uint32_t Y[4];
994 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200995
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
997 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
998 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
999 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001000
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1002 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]);
1003 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 +02001004 }
1005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 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 +02001007
Gilles Peskine5197c662020-08-26 17:03:24 +02001008 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1010 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1011 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1012 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001013
Gilles Peskine5197c662020-08-26 17:03:24 +02001014 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1016 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1017 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1018 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001019
Gilles Peskine5197c662020-08-26 17:03:24 +02001020 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1022 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1023 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001025
Gilles Peskine5197c662020-08-26 17:03:24 +02001026 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1028 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1029 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001031
Gilles Peskine449bd832023-01-11 14:50:10 +01001032 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1033 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1034 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1035 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001036
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001038
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001040}
1041#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1042
Gilles Peskine0de8f852023-03-16 17:14:59 +01001043#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001044/* VIA Padlock and our intrinsics-based implementation of AESNI require
1045 * the round keys to be aligned on a 16-byte boundary. We take care of this
1046 * before creating them, but the AES context may have moved (this can happen
1047 * if the library is called from a language with managed memory), and in later
1048 * calls it might have a different alignment with respect to 16-byte memory.
1049 * So we may need to realign.
1050 */
1051static void aes_maybe_realign(mbedtls_aes_context *ctx)
1052{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001053 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1054 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001055 memmove(ctx->buf + new_offset, // new address
1056 ctx->buf + ctx->rk_offset, // current address
1057 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1058 ctx->rk_offset = new_offset;
1059 }
1060}
1061#endif
1062
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001063/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001064 * AES-ECB block encryption/decryption
1065 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001066int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1067 int mode,
1068 const unsigned char input[16],
1069 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001070{
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001072 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001074
Gilles Peskine0de8f852023-03-16 17:14:59 +01001075#if defined(MAY_NEED_TO_ALIGN)
1076 aes_maybe_realign(ctx);
1077#endif
1078
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001079#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1081 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1082 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001083#endif
1084
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001085#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001086 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001087 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1088 }
1089#endif
1090
Jerry Yu9e628622023-08-17 11:20:09 +08001091#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001093 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001094 }
1095#endif
1096
Jerry Yu29c91ba2023-08-04 11:02:04 +08001097#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 if (mode == MBEDTLS_AES_ENCRYPT) {
1099 return mbedtls_internal_aes_encrypt(ctx, input, output);
1100 } else {
1101 return mbedtls_internal_aes_decrypt(ctx, input, output);
1102 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001103#endif
1104
Paul Bakker5121ce52009-01-03 21:22:43 +00001105}
1106
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001108
Paul Bakker5121ce52009-01-03 21:22:43 +00001109/*
1110 * AES-CBC buffer encryption/decryption
1111 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001112int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1113 int mode,
1114 size_t length,
1115 unsigned char iv[16],
1116 const unsigned char *input,
1117 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001118{
Gilles Peskine7820a572021-07-07 21:08:28 +02001119 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001120 unsigned char temp[16];
1121
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001123 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001125
Paul Elliott2ad93672023-08-11 11:07:06 +01001126 /* Nothing to do if length is zero. */
1127 if (length == 0) {
1128 return 0;
1129 }
1130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 if (length % 16) {
1132 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1133 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001134
Jerry Yu9e628622023-08-17 11:20:09 +08001135#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 if (aes_padlock_ace > 0) {
1137 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1138 return 0;
1139 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001140
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001141 // If padlock data misaligned, we just fall back to
1142 // unaccelerated mode
1143 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001144 }
1145#endif
1146
Dave Rodgman906c63c2023-06-14 17:53:51 +01001147 const unsigned char *ivp = iv;
1148
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 if (mode == MBEDTLS_AES_DECRYPT) {
1150 while (length > 0) {
1151 memcpy(temp, input, 16);
1152 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1153 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001154 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001156 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001157 * the result for the next block in CBC, and the cost of transferring that data from
1158 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001159 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001160
Gilles Peskine449bd832023-01-11 14:50:10 +01001161 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001162
1163 input += 16;
1164 output += 16;
1165 length -= 16;
1166 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 } else {
1168 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001169 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001170
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1172 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001173 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001174 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001175 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001176
1177 input += 16;
1178 output += 16;
1179 length -= 16;
1180 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001181 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001182 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001183 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001184
Gilles Peskine7820a572021-07-07 21:08:28 +02001185exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001187}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001188#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001189
Aorimn5f778012016-06-09 23:22:58 +02001190#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001191
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001192typedef unsigned char mbedtls_be128[16];
1193
1194/*
1195 * GF(2^128) multiplication function
1196 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001197 * This function multiplies a field element by x in the polynomial field
1198 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001199 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001200 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001201 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001202#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001203MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001204#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001205static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001206 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001207{
1208 uint64_t a, b, ra, rb;
1209
Gilles Peskine449bd832023-01-11 14:50:10 +01001210 a = MBEDTLS_GET_UINT64_LE(x, 0);
1211 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001212
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1214 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001215
Gilles Peskine449bd832023-01-11 14:50:10 +01001216 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1217 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001218}
1219
Aorimn5f778012016-06-09 23:22:58 +02001220/*
1221 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001222 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001223 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001224 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001225 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001226#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001227MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001228#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001229int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1230 int mode,
1231 size_t length,
1232 const unsigned char data_unit[16],
1233 const unsigned char *input,
1234 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001235{
Janos Follath24eed8d2019-11-22 13:21:35 +00001236 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001237 size_t blocks = length / 16;
1238 size_t leftover = length % 16;
1239 unsigned char tweak[16];
1240 unsigned char prev_tweak[16];
1241 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001242
Gilles Peskine449bd832023-01-11 14:50:10 +01001243 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001244 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001246
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001247 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001249 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 }
Aorimn5f778012016-06-09 23:22:58 +02001251
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001252 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001254 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 }
Aorimn5f778012016-06-09 23:22:58 +02001256
Jaeden Amerod82cd862018-04-28 15:02:45 +01001257 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1259 data_unit, tweak);
1260 if (ret != 0) {
1261 return ret;
1262 }
Aorimn5f778012016-06-09 23:22:58 +02001263
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001265 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 /* We are on the last block in a decrypt operation that has
1267 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001268 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001269 * the leftovers and then update the current tweak for use on this,
1270 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 memcpy(prev_tweak, tweak, sizeof(tweak));
1272 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 }
1274
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1278 if (ret != 0) {
1279 return ret;
1280 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001283
1284 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001286
1287 output += 16;
1288 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001289 }
1290
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001292 /* If we are on the leftover bytes in a decrypt operation, we need to
1293 * use the previous tweak for these bytes (as saved in prev_tweak). */
1294 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001295
Jaeden Amerod82cd862018-04-28 15:02:45 +01001296 /* We are now on the final part of the data unit, which doesn't divide
1297 * evenly by 16. It's time for ciphertext stealing. */
1298 size_t i;
1299 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001300
Jaeden Amerod82cd862018-04-28 15:02:45 +01001301 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001302 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001303 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001304 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001305 }
Aorimn5f778012016-06-09 23:22:58 +02001306
Dave Rodgman069e7f42022-11-24 19:37:26 +00001307 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001309
Jaeden Amerod82cd862018-04-28 15:02:45 +01001310 /* Copy ciphertext bytes from the previous block for input in this
1311 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001313
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1315 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001316 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 }
Aorimn5f778012016-06-09 23:22:58 +02001318
Jaeden Amerod82cd862018-04-28 15:02:45 +01001319 /* Write the result back to the previous block, overriding the previous
1320 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001321 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001322 }
1323
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001325}
1326#endif /* MBEDTLS_CIPHER_MODE_XTS */
1327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001328#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001329/*
1330 * AES-CFB128 buffer encryption/decryption
1331 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001332int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1333 int mode,
1334 size_t length,
1335 size_t *iv_off,
1336 unsigned char iv[16],
1337 const unsigned char *input,
1338 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001339{
Paul Bakker27fdf462011-06-09 13:55:13 +00001340 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001341 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001342 size_t n;
1343
Gilles Peskine449bd832023-01-11 14:50:10 +01001344 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001345 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001347
1348 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001349
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 if (n > 15) {
1351 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1352 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001353
Gilles Peskine449bd832023-01-11 14:50:10 +01001354 if (mode == MBEDTLS_AES_DECRYPT) {
1355 while (length--) {
1356 if (n == 0) {
1357 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1358 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001359 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001361 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001362
1363 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001365 iv[n] = (unsigned char) c;
1366
Gilles Peskine449bd832023-01-11 14:50:10 +01001367 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001368 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 } else {
1370 while (length--) {
1371 if (n == 0) {
1372 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1373 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001374 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001375 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001376 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001377
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001379
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001381 }
1382 }
1383
1384 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001385 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001386
Gilles Peskine7820a572021-07-07 21:08:28 +02001387exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001389}
Paul Bakker556efba2014-01-24 15:38:12 +01001390
1391/*
1392 * AES-CFB8 buffer encryption/decryption
1393 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001394int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1395 int mode,
1396 size_t length,
1397 unsigned char iv[16],
1398 const unsigned char *input,
1399 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001400{
Gilles Peskine7820a572021-07-07 21:08:28 +02001401 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001402 unsigned char c;
1403 unsigned char ov[17];
1404
Gilles Peskine449bd832023-01-11 14:50:10 +01001405 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001406 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001407 }
1408 while (length--) {
1409 memcpy(ov, iv, 16);
1410 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1411 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001412 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001413 }
Paul Bakker556efba2014-01-24 15:38:12 +01001414
Gilles Peskine449bd832023-01-11 14:50:10 +01001415 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001416 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001417 }
Paul Bakker556efba2014-01-24 15:38:12 +01001418
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001420
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001422 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 }
Paul Bakker556efba2014-01-24 15:38:12 +01001424
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001426 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001427 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001428
Gilles Peskine7820a572021-07-07 21:08:28 +02001429exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001430 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001431}
Simon Butcher76a5b222018-04-22 22:57:27 +01001432#endif /* MBEDTLS_CIPHER_MODE_CFB */
1433
1434#if defined(MBEDTLS_CIPHER_MODE_OFB)
1435/*
1436 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1437 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001438int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1439 size_t length,
1440 size_t *iv_off,
1441 unsigned char iv[16],
1442 const unsigned char *input,
1443 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001444{
Simon Butcherad4e4932018-04-29 00:43:47 +01001445 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001446 size_t n;
1447
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001448 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001449
Gilles Peskine449bd832023-01-11 14:50:10 +01001450 if (n > 15) {
1451 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1452 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001453
Gilles Peskine449bd832023-01-11 14:50:10 +01001454 while (length--) {
1455 if (n == 0) {
1456 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1457 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001458 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001460 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001461 *output++ = *input++ ^ iv[n];
1462
Gilles Peskine449bd832023-01-11 14:50:10 +01001463 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001464 }
1465
1466 *iv_off = n;
1467
Simon Butcherad4e4932018-04-29 00:43:47 +01001468exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001469 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001470}
1471#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001473#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001474/*
1475 * AES-CTR buffer encryption/decryption
1476 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001477int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1478 size_t length,
1479 size_t *nc_off,
1480 unsigned char nonce_counter[16],
1481 unsigned char stream_block[16],
1482 const unsigned char *input,
1483 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001484{
Paul Bakker369e14b2012-04-18 14:16:09 +00001485 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001486 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001487 size_t n;
1488
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001489 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001490
Gilles Peskine449bd832023-01-11 14:50:10 +01001491 if (n > 0x0F) {
1492 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1493 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001494
Gilles Peskine449bd832023-01-11 14:50:10 +01001495 while (length--) {
1496 if (n == 0) {
1497 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1498 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001499 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001500 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001501
Gilles Peskine449bd832023-01-11 14:50:10 +01001502 for (i = 16; i > 0; i--) {
1503 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001504 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001505 }
1506 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001507 }
1508 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001509 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001510
Gilles Peskine449bd832023-01-11 14:50:10 +01001511 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001512 }
1513
1514 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001515 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001516
Gilles Peskine7820a572021-07-07 21:08:28 +02001517exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001518 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001519}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001520#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001521
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001522#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001525/*
1526 * AES test vectors from:
1527 *
1528 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1529 */
Yanray Wang62c99912023-05-11 11:06:53 +08001530static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001531{
1532 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1533 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001534#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001535 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1536 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1537 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1538 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001539#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001540};
1541
Yanray Wang62c99912023-05-11 11:06:53 +08001542static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001543{
1544 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1545 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001546#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001547 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1548 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1549 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1550 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001551#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001552};
1553
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001554#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001555static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001556{
1557 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1558 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001559#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001560 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1561 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1562 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1563 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001564#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001565};
1566
Yanray Wang62c99912023-05-11 11:06:53 +08001567static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001568{
1569 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1570 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001571#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001572 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1573 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1574 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1575 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001576#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001577};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001578#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001580#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001581/*
1582 * AES-CFB128 test vectors from:
1583 *
1584 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1585 */
Yanray Wang62c99912023-05-11 11:06:53 +08001586static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001587{
1588 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1589 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001590#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001591 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1592 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1593 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1594 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1595 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1596 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1597 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001598#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001599};
1600
1601static const unsigned char aes_test_cfb128_iv[16] =
1602{
1603 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1604 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1605};
1606
1607static const unsigned char aes_test_cfb128_pt[64] =
1608{
1609 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1610 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1611 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1612 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1613 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1614 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1615 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1616 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1617};
1618
Yanray Wang62c99912023-05-11 11:06:53 +08001619static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001620{
1621 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1622 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1623 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1624 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1625 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1626 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1627 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1628 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001629#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001630 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1631 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1632 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1633 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1634 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1635 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1636 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1637 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1638 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1639 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1640 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1641 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1642 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1643 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1644 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1645 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001646#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001647};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001648#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001649
Simon Butcherad4e4932018-04-29 00:43:47 +01001650#if defined(MBEDTLS_CIPHER_MODE_OFB)
1651/*
1652 * AES-OFB test vectors from:
1653 *
Simon Butcher5db13622018-06-04 22:11:25 +01001654 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001655 */
Yanray Wang62c99912023-05-11 11:06:53 +08001656static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001657{
1658 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1659 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001660#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001661 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1662 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1663 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1664 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1665 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1666 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1667 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001668#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001669};
1670
1671static const unsigned char aes_test_ofb_iv[16] =
1672{
1673 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1674 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1675};
1676
1677static const unsigned char aes_test_ofb_pt[64] =
1678{
1679 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1680 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1681 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1682 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1683 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1684 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1685 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1686 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1687};
1688
Yanray Wang62c99912023-05-11 11:06:53 +08001689static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001690{
1691 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1692 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1693 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1694 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1695 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1696 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1697 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1698 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001699#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001700 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1701 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1702 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1703 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1704 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1705 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1706 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1707 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1708 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1709 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1710 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1711 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1712 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1713 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1714 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1715 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001716#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001717};
1718#endif /* MBEDTLS_CIPHER_MODE_OFB */
1719
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001720#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001721/*
1722 * AES-CTR test vectors from:
1723 *
1724 * http://www.faqs.org/rfcs/rfc3686.html
1725 */
1726
Yanray Wang62c99912023-05-11 11:06:53 +08001727static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001728{
1729 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1730 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1731 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1732 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1733 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1734 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1735};
1736
Yanray Wang62c99912023-05-11 11:06:53 +08001737static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001738{
1739 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1741 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1742 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1743 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1744 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1745};
1746
Yanray Wang62c99912023-05-11 11:06:53 +08001747static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001748{
1749 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1750 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001751 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1752 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1753 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1754 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1755
1756 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1757 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1758 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1759 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1760 0x20, 0x21, 0x22, 0x23 }
1761};
1762
Yanray Wang62c99912023-05-11 11:06:53 +08001763static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001764{
1765 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1766 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1767 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1768 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1769 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1770 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1771 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1772 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1773 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1774 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1775 0x25, 0xB2, 0x07, 0x2F }
1776};
1777
1778static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001779{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001780#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001781
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001782#if defined(MBEDTLS_CIPHER_MODE_XTS)
1783/*
1784 * AES-XTS test vectors from:
1785 *
1786 * IEEE P1619/D16 Annex B
1787 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1788 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1789 */
1790static const unsigned char aes_test_xts_key[][32] =
1791{
1792 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1796 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1797 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1798 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1799 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1800 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1801 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1802 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1803 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1804};
1805
1806static const unsigned char aes_test_xts_pt32[][32] =
1807{
1808 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1812 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1813 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1814 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1815 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1816 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1817 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1818 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1819 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1820};
1821
1822static const unsigned char aes_test_xts_ct32[][32] =
1823{
1824 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1825 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1826 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1827 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1828 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1829 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1830 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1831 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1832 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1833 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1834 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1835 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1836};
1837
1838static const unsigned char aes_test_xts_data_unit[][16] =
1839{
Gilles Peskine449bd832023-01-11 14:50:10 +01001840 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1842 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1844 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001846};
1847
1848#endif /* MBEDTLS_CIPHER_MODE_XTS */
1849
Paul Bakker5121ce52009-01-03 21:22:43 +00001850/*
1851 * Checkup routine
1852 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001853int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001854{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001855 int ret = 0, i, j, u, mode;
1856 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001857 unsigned char key[32];
1858 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001859 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001860#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1861 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001862 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001863#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001864#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001865 unsigned char prv[16];
1866#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001867#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1868 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001869 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001870#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001871#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001872 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001873#endif
1874#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001875 unsigned char nonce_counter[16];
1876 unsigned char stream_block[16];
1877#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001878 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001879
Gilles Peskine449bd832023-01-11 14:50:10 +01001880 memset(key, 0, 32);
1881 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001882
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001883 if (verbose != 0) {
1884#if defined(MBEDTLS_AES_ALT)
1885 mbedtls_printf(" AES note: alternative implementation.\n");
1886#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001887#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001888#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001889 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001890#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001891 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001892#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001893#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001894#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001895 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1896 mbedtls_printf(" AES note: using AESNI.\n");
1897 } else
1898#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001899#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001900 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1901 mbedtls_printf(" AES note: using VIA Padlock.\n");
1902 } else
1903#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001904#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001905 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001906 mbedtls_printf(" AES note: using AESCE.\n");
1907 } else
1908#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001909 {
1910#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1911 mbedtls_printf(" AES note: built-in implementation.\n");
1912#endif
1913 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001914#endif /* MBEDTLS_AES_ALT */
1915 }
1916
Paul Bakker5121ce52009-01-03 21:22:43 +00001917 /*
1918 * ECB mode
1919 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001920 {
1921 static const int num_tests =
1922 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001923
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001924 for (i = 0; i < num_tests << 1; i++) {
1925 u = i >> 1;
1926 keybits = 128 + u * 64;
1927 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001928
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001929 if (verbose != 0) {
1930 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1931 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1932 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001933
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001934 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001935
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001936 if (mode == MBEDTLS_AES_DECRYPT) {
1937 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1938 aes_tests = aes_test_ecb_dec[u];
1939 } else {
1940 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1941 aes_tests = aes_test_ecb_enc[u];
1942 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001943
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001944 /*
1945 * AES-192 is an optional feature that may be unavailable when
1946 * there is an alternative underlying implementation i.e. when
1947 * MBEDTLS_AES_ALT is defined.
1948 */
1949 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1950 mbedtls_printf("skipped\n");
1951 continue;
1952 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001953 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001954 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001955
1956 for (j = 0; j < 10000; j++) {
1957 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1958 if (ret != 0) {
1959 goto exit;
1960 }
1961 }
1962
1963 if (memcmp(buf, aes_tests, 16) != 0) {
1964 ret = 1;
1965 goto exit;
1966 }
1967
1968 if (verbose != 0) {
1969 mbedtls_printf("passed\n");
1970 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001971 }
1972
Gilles Peskine449bd832023-01-11 14:50:10 +01001973 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001974 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001975 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001976 }
1977
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001978#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001979 /*
1980 * CBC mode
1981 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001982 {
1983 static const int num_tests =
1984 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001985
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001986 for (i = 0; i < num_tests << 1; i++) {
1987 u = i >> 1;
1988 keybits = 128 + u * 64;
1989 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001990
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001991 if (verbose != 0) {
1992 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1993 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001994 }
1995
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001996 memset(iv, 0, 16);
1997 memset(prv, 0, 16);
1998 memset(buf, 0, 16);
1999
2000 if (mode == MBEDTLS_AES_DECRYPT) {
2001 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2002 aes_tests = aes_test_cbc_dec[u];
2003 } else {
2004 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2005 aes_tests = aes_test_cbc_enc[u];
2006 }
2007
2008 /*
2009 * AES-192 is an optional feature that may be unavailable when
2010 * there is an alternative underlying implementation i.e. when
2011 * MBEDTLS_AES_ALT is defined.
2012 */
2013 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2014 mbedtls_printf("skipped\n");
2015 continue;
2016 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002017 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002018 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002019
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002020 for (j = 0; j < 10000; j++) {
2021 if (mode == MBEDTLS_AES_ENCRYPT) {
2022 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002023
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002024 memcpy(tmp, prv, 16);
2025 memcpy(prv, buf, 16);
2026 memcpy(buf, tmp, 16);
2027 }
2028
2029 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2030 if (ret != 0) {
2031 goto exit;
2032 }
2033
2034 }
2035
2036 if (memcmp(buf, aes_tests, 16) != 0) {
2037 ret = 1;
2038 goto exit;
2039 }
2040
2041 if (verbose != 0) {
2042 mbedtls_printf("passed\n");
2043 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002044 }
2045
Gilles Peskine449bd832023-01-11 14:50:10 +01002046 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002047 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002048 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002049 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002050#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002051
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002052#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002053 /*
2054 * CFB128 mode
2055 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002056 {
2057 static const int num_tests =
2058 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002059
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002060 for (i = 0; i < num_tests << 1; i++) {
2061 u = i >> 1;
2062 keybits = 128 + u * 64;
2063 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002064
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002065 if (verbose != 0) {
2066 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2067 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2068 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002069
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002070 memcpy(iv, aes_test_cfb128_iv, 16);
2071 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002072
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002073 offset = 0;
2074 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2075 /*
2076 * AES-192 is an optional feature that may be unavailable when
2077 * there is an alternative underlying implementation i.e. when
2078 * MBEDTLS_AES_ALT is defined.
2079 */
2080 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2081 mbedtls_printf("skipped\n");
2082 continue;
2083 } else if (ret != 0) {
2084 goto exit;
2085 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002086
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002087 if (mode == MBEDTLS_AES_DECRYPT) {
2088 memcpy(buf, aes_test_cfb128_ct[u], 64);
2089 aes_tests = aes_test_cfb128_pt;
2090 } else {
2091 memcpy(buf, aes_test_cfb128_pt, 64);
2092 aes_tests = aes_test_cfb128_ct[u];
2093 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002094
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002095 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2096 if (ret != 0) {
2097 goto exit;
2098 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002099
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002100 if (memcmp(buf, aes_tests, 64) != 0) {
2101 ret = 1;
2102 goto exit;
2103 }
2104
2105 if (verbose != 0) {
2106 mbedtls_printf("passed\n");
2107 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002108 }
2109
Gilles Peskine449bd832023-01-11 14:50:10 +01002110 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002111 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002112 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002113 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002114#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002115
Simon Butcherad4e4932018-04-29 00:43:47 +01002116#if defined(MBEDTLS_CIPHER_MODE_OFB)
2117 /*
2118 * OFB mode
2119 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002120 {
2121 static const int num_tests =
2122 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002123
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002124 for (i = 0; i < num_tests << 1; i++) {
2125 u = i >> 1;
2126 keybits = 128 + u * 64;
2127 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002128
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002129 if (verbose != 0) {
2130 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2131 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2132 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002133
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002134 memcpy(iv, aes_test_ofb_iv, 16);
2135 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002136
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002137 offset = 0;
2138 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2139 /*
2140 * AES-192 is an optional feature that may be unavailable when
2141 * there is an alternative underlying implementation i.e. when
2142 * MBEDTLS_AES_ALT is defined.
2143 */
2144 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2145 mbedtls_printf("skipped\n");
2146 continue;
2147 } else if (ret != 0) {
2148 goto exit;
2149 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002150
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002151 if (mode == MBEDTLS_AES_DECRYPT) {
2152 memcpy(buf, aes_test_ofb_ct[u], 64);
2153 aes_tests = aes_test_ofb_pt;
2154 } else {
2155 memcpy(buf, aes_test_ofb_pt, 64);
2156 aes_tests = aes_test_ofb_ct[u];
2157 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002158
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002159 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2160 if (ret != 0) {
2161 goto exit;
2162 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002163
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002164 if (memcmp(buf, aes_tests, 64) != 0) {
2165 ret = 1;
2166 goto exit;
2167 }
2168
2169 if (verbose != 0) {
2170 mbedtls_printf("passed\n");
2171 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002172 }
2173
Gilles Peskine449bd832023-01-11 14:50:10 +01002174 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002175 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002176 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002177 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002178#endif /* MBEDTLS_CIPHER_MODE_OFB */
2179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002180#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002181 /*
2182 * CTR mode
2183 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002184 {
2185 static const int num_tests =
2186 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002187
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002188 for (i = 0; i < num_tests << 1; i++) {
2189 u = i >> 1;
2190 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002191
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002192 if (verbose != 0) {
2193 mbedtls_printf(" AES-CTR-128 (%s): ",
2194 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2195 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002196
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002197 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2198 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002199
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002200 offset = 0;
2201 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2202 goto exit;
2203 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002204
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002205 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002206
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002207 if (mode == MBEDTLS_AES_DECRYPT) {
2208 memcpy(buf, aes_test_ctr_ct[u], len);
2209 aes_tests = aes_test_ctr_pt[u];
2210 } else {
2211 memcpy(buf, aes_test_ctr_pt[u], len);
2212 aes_tests = aes_test_ctr_ct[u];
2213 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002214
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002215 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2216 stream_block, buf, buf);
2217 if (ret != 0) {
2218 goto exit;
2219 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002220
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002221 if (memcmp(buf, aes_tests, len) != 0) {
2222 ret = 1;
2223 goto exit;
2224 }
2225
2226 if (verbose != 0) {
2227 mbedtls_printf("passed\n");
2228 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002229 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002230 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002231
Gilles Peskine449bd832023-01-11 14:50:10 +01002232 if (verbose != 0) {
2233 mbedtls_printf("\n");
2234 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002235#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002236
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002237#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002238 /*
2239 * XTS mode
2240 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002241 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002242 static const int num_tests =
2243 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2244 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002245
Gilles Peskine449bd832023-01-11 14:50:10 +01002246 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002247
Gilles Peskine449bd832023-01-11 14:50:10 +01002248 for (i = 0; i < num_tests << 1; i++) {
2249 const unsigned char *data_unit;
2250 u = i >> 1;
2251 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002252
Gilles Peskine449bd832023-01-11 14:50:10 +01002253 if (verbose != 0) {
2254 mbedtls_printf(" AES-XTS-128 (%s): ",
2255 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2256 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002257
Gilles Peskine449bd832023-01-11 14:50:10 +01002258 memset(key, 0, sizeof(key));
2259 memcpy(key, aes_test_xts_key[u], 32);
2260 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002261
Gilles Peskine449bd832023-01-11 14:50:10 +01002262 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002263
Gilles Peskine449bd832023-01-11 14:50:10 +01002264 if (mode == MBEDTLS_AES_DECRYPT) {
2265 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2266 if (ret != 0) {
2267 goto exit;
2268 }
2269 memcpy(buf, aes_test_xts_ct32[u], len);
2270 aes_tests = aes_test_xts_pt32[u];
2271 } else {
2272 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2273 if (ret != 0) {
2274 goto exit;
2275 }
2276 memcpy(buf, aes_test_xts_pt32[u], len);
2277 aes_tests = aes_test_xts_ct32[u];
2278 }
2279
2280
2281 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2282 buf, buf);
2283 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002284 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002285 }
2286
2287 if (memcmp(buf, aes_tests, len) != 0) {
2288 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002289 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002290 }
2291
2292 if (verbose != 0) {
2293 mbedtls_printf("passed\n");
2294 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002295 }
2296
Gilles Peskine449bd832023-01-11 14:50:10 +01002297 if (verbose != 0) {
2298 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002299 }
2300
Gilles Peskine449bd832023-01-11 14:50:10 +01002301 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002302 }
2303#endif /* MBEDTLS_CIPHER_MODE_XTS */
2304
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002305 ret = 0;
2306
2307exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002308 if (ret != 0 && verbose != 0) {
2309 mbedtls_printf("failed\n");
2310 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002311
Gilles Peskine449bd832023-01-11 14:50:10 +01002312 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002313
Gilles Peskine449bd832023-01-11 14:50:10 +01002314 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002315}
2316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002317#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002318
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002319#endif /* MBEDTLS_AES_C */