blob: 52e361a28321cb0bb3ae94ea05cc35db0553bd46 [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 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Jerry Yuba42b072023-08-10 12:53:26 +080037#if defined(__aarch64__)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yufce351d2023-08-04 17:13:36 +080043#if defined(MBEDTLS_HAVE_ASM) && \
Jerry Yu5fcdd6a2023-08-07 15:32:58 +080044 (defined(__amd64__) || defined(__x86_64__))
Jerry Yu02b15192023-04-23 14:43:19 +080045#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080046#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080047#endif
48#endif
49
Jerry Yu13696bb2023-08-10 13:36:32 +080050#if defined(__i386__)
Jerry Yuc4508c02023-08-08 12:57:06 +080051#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
52#error "MBEDTLS_AES_USE_HARDWARE_ONLY not supported yet for i386."
Jerry Yu02b15192023-04-23 14:43:19 +080053#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080054
55#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
56#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
57#endif
Jerry Yu02b15192023-04-23 14:43:19 +080058#endif
59
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000061#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000062#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000064#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010065#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080066#if defined(MBEDTLS_AESCE_C)
67#include "aesce.h"
68#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000069
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000070#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010071
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020073
Gilles Peskine0f454e42023-03-16 14:58:46 +010074#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000075static int aes_padlock_ace = -1;
76#endif
77
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000079/*
80 * Forward S-box
81 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010082#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
83 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000084static const unsigned char FSb[256] =
85{
86 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
87 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
88 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
89 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
90 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
91 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
92 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
93 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
94 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
95 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
96 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
97 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
98 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
99 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
100 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
101 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
102 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
103 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
104 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
105 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
106 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
107 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
108 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
109 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
110 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
111 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
112 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
113 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
114 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
115 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
116 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
117 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
118};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100119#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
120 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000121
122/*
123 * Forward tables
124 */
125#define FT \
126\
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
128 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
129 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
130 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
131 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
132 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
133 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
134 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
135 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
136 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
137 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
138 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
139 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
140 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
141 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
142 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
143 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
144 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
145 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
146 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
147 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
148 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
149 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
150 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
151 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
152 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
153 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
154 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
155 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
156 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
157 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
158 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
159 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
160 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
161 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
162 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
163 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
164 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
165 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
166 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
167 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
168 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
169 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
170 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
171 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
172 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
173 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
174 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
175 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
176 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
177 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
178 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
179 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
180 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
181 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
182 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
183 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
184 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
185 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
186 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
187 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
188 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
189 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
190 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 +0000191
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100192#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100193#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000194static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000195#undef V
196
Hanno Beckerad049a92017-06-19 16:31:54 +0100197#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000201#undef V
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000204static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000205#undef V
206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000208static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000209#undef V
210
Hanno Becker177d3cf2017-06-07 15:52:48 +0100211#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200212
Dave Rodgman1be24632023-06-29 12:01:24 +0100213#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
214
Paul Bakker5121ce52009-01-03 21:22:43 +0000215#undef FT
216
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100217#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000218/*
219 * Reverse S-box
220 */
221static const unsigned char RSb[256] =
222{
223 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
224 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
225 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
226 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
227 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
228 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
229 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
230 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
231 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
232 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
233 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
234 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
235 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
236 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
237 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
238 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
239 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
240 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
241 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
242 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
243 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
244 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
245 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
246 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
247 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
248 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
249 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
250 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
251 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
252 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
253 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
254 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
255};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100256#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258/*
259 * Reverse tables
260 */
261#define RT \
262\
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
264 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
265 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
266 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
267 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
268 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
269 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
270 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
271 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
272 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
273 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
274 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
275 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
276 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
277 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
278 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
279 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
280 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
281 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
282 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
283 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
284 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
285 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
286 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
287 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
288 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
289 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
290 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
291 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
292 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
293 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
294 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
295 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
296 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
297 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
298 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
299 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
300 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
301 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
302 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
303 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
304 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
305 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
306 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
307 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
308 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
309 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
310 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
311 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
312 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
313 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
314 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
315 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
316 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
317 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
318 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
319 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
320 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
321 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
322 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
323 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
324 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
325 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
326 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 +0000327
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100328#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
329
Gilles Peskine449bd832023-01-11 14:50:10 +0100330#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000331static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000332#undef V
333
Hanno Beckerad049a92017-06-19 16:31:54 +0100334#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000338#undef V
339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000341static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000342#undef V
343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000346#undef V
347
Hanno Becker177d3cf2017-06-07 15:52:48 +0100348#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200349
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800350#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
351
Paul Bakker5121ce52009-01-03 21:22:43 +0000352#undef RT
353
Dave Rodgman34152a42023-06-27 18:31:24 +0100354#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000355/*
356 * Round constants
357 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000358static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000359{
360 0x00000001, 0x00000002, 0x00000004, 0x00000008,
361 0x00000010, 0x00000020, 0x00000040, 0x00000080,
362 0x0000001B, 0x00000036
363};
Dave Rodgman34152a42023-06-27 18:31:24 +0100364#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000367
368/*
369 * Forward S-box & tables
370 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100371#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
372 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000373static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100374#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
375 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100376#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200377static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100378#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200379static uint32_t FT1[256];
380static uint32_t FT2[256];
381static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100382#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100383#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
385/*
386 * Reverse S-box & tables
387 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100388#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000389static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100390#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100391
392#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000393static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100394#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000395static uint32_t RT1[256];
396static uint32_t RT2[256];
397static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100398#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100399#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
Dave Rodgman8c753f92023-06-27 18:16:13 +0100401#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000402/*
403 * Round constants
404 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000405static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
407/*
408 * Tables generation code
409 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100410#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
411#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
412#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
414static int aes_init_done = 0;
415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000417{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800418 int i;
419 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800420 uint8_t pow[256];
421 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
423 /*
424 * compute pow and log tables over GF(2^8)
425 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800428 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800429 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 }
431
432 /*
433 * calculate the round constants
434 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800436 RCON[i] = x;
437 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 }
439
440 /*
441 * generate the forward and reverse S-boxes
442 */
443 FSb[0x00] = 0x63;
444 RSb[0x63] = 0x00;
445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000447 x = pow[255 - log[i]];
448
Yanray Wangfe944ce2023-06-26 18:16:01 +0800449 y = x; y = (y << 1) | (y >> 7);
450 x ^= y; y = (y << 1) | (y >> 7);
451 x ^= y; y = (y << 1) | (y >> 7);
452 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 x ^= y ^ 0x63;
454
Yanray Wangfe944ce2023-06-26 18:16:01 +0800455 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 RSb[x] = (unsigned char) i;
457 }
458
459 /*
460 * generate the forward and reverse tables
461 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800464 y = XTIME(x);
465 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 FT0[i] = ((uint32_t) y) ^
468 ((uint32_t) x << 8) ^
469 ((uint32_t) x << 16) ^
470 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
Hanno Beckerad049a92017-06-19 16:31:54 +0100472#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 FT1[i] = ROTL8(FT0[i]);
474 FT2[i] = ROTL8(FT1[i]);
475 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100476#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
478 x = RSb[i];
479
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100480#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
482 ((uint32_t) MUL(0x09, x) << 8) ^
483 ((uint32_t) MUL(0x0D, x) << 16) ^
484 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
Hanno Beckerad049a92017-06-19 16:31:54 +0100486#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 RT1[i] = ROTL8(RT0[i]);
488 RT2[i] = ROTL8(RT1[i]);
489 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100490#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100491#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000492 }
493}
494
Dave Rodgman8c753f92023-06-27 18:16:13 +0100495#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
496
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200497#undef ROTL8
498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
Hanno Beckerad049a92017-06-19 16:31:54 +0100501#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
504#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
505#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200506
507#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100508#define AES_RT1(idx) ROTL8(RT0[idx])
509#define AES_RT2(idx) ROTL16(RT0[idx])
510#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200511
512#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100513#define AES_FT1(idx) ROTL8(FT0[idx])
514#define AES_FT2(idx) ROTL16(FT0[idx])
515#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200516
Hanno Becker177d3cf2017-06-07 15:52:48 +0100517#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200518
519#define AES_RT0(idx) RT0[idx]
520#define AES_RT1(idx) RT1[idx]
521#define AES_RT2(idx) RT2[idx]
522#define AES_RT3(idx) RT3[idx]
523
524#define AES_FT0(idx) FT0[idx]
525#define AES_FT1(idx) FT1[idx]
526#define AES_FT2(idx) FT2[idx]
527#define AES_FT3(idx) FT3[idx]
528
Hanno Becker177d3cf2017-06-07 15:52:48 +0100529#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200532{
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200534}
535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200537{
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200539 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200543}
544
Jaeden Amero9366feb2018-05-29 18:55:17 +0100545#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100546void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100547{
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 mbedtls_aes_init(&ctx->crypt);
549 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100550}
551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100553{
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100555 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 }
Simon Butcher5201e412018-12-06 17:40:14 +0000557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 mbedtls_aes_free(&ctx->crypt);
559 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100560}
561#endif /* MBEDTLS_CIPHER_MODE_XTS */
562
Gilles Peskine0de8f852023-03-16 17:14:59 +0100563/* Some implementations need the round keys to be aligned.
564 * Return an offset to be added to buf, such that (buf + offset) is
565 * correctly aligned.
566 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
567 * i.e. an offset of 1 means 4 bytes and so on.
568 */
569#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100570 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100571#define MAY_NEED_TO_ALIGN
572#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100573
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100574#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
575 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100576static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
577{
578#if defined(MAY_NEED_TO_ALIGN)
579 int align_16_bytes = 0;
580
581#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
582 if (aes_padlock_ace == -1) {
583 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
584 }
585 if (aes_padlock_ace) {
586 align_16_bytes = 1;
587 }
588#endif
589
Gilles Peskine9c682e72023-03-16 17:21:33 +0100590#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100591 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
592 align_16_bytes = 1;
593 }
594#endif
595
596 if (align_16_bytes) {
597 /* These implementations needs 16-byte alignment
598 * for the round key array. */
599 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
600 if (delta == 0) {
601 return 0;
602 } else {
603 return 4 - delta; // 16 bytes = 4 uint32_t
604 }
605 }
606#else /* MAY_NEED_TO_ALIGN */
607 (void) buf;
608#endif /* MAY_NEED_TO_ALIGN */
609
610 return 0;
611}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100612#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
613 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100614
Paul Bakker5121ce52009-01-03 21:22:43 +0000615/*
616 * AES key schedule (encryption)
617 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200618#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100619int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
620 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000621{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800622#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Paul Bakker23986e52011-04-24 08:57:21 +0000623 unsigned int i;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800624#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000625 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800629#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 case 192: ctx->nr = 12; break;
631 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800632#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635
Simon Butcher5201e412018-12-06 17:40:14 +0000636#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000638 aes_gen_tables();
639 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000640 }
641#endif
642
Gilles Peskine0de8f852023-03-16 17:14:59 +0100643 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100644 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000645
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100646#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
648 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
649 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100650#endif
651
Jerry Yu3f2fb712023-01-10 17:05:42 +0800652#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
653 if (mbedtls_aesce_has_support()) {
654 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
655 }
656#endif
657
Jerry Yu29c91ba2023-08-04 11:02:04 +0800658#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100659 for (i = 0; i < (keybits >> 5); i++) {
660 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 }
662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 case 10:
665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
669 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
670 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
671 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000672
673 RK[5] = RK[1] ^ RK[4];
674 RK[6] = RK[2] ^ RK[5];
675 RK[7] = RK[3] ^ RK[6];
676 }
677 break;
678
Arto Kinnunen732ca322023-04-14 14:26:10 +0800679#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000680 case 12:
681
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
685 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
687 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
689 RK[7] = RK[1] ^ RK[6];
690 RK[8] = RK[2] ^ RK[7];
691 RK[9] = RK[3] ^ RK[8];
692 RK[10] = RK[4] ^ RK[9];
693 RK[11] = RK[5] ^ RK[10];
694 }
695 break;
696
697 case 14:
698
Gilles Peskine449bd832023-01-11 14:50:10 +0100699 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000700 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
702 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
703 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
704 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
706 RK[9] = RK[1] ^ RK[8];
707 RK[10] = RK[2] ^ RK[9];
708 RK[11] = RK[3] ^ RK[10];
709
710 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
712 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
713 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
714 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000715
716 RK[13] = RK[5] ^ RK[12];
717 RK[14] = RK[6] ^ RK[13];
718 RK[15] = RK[7] ^ RK[14];
719 }
720 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800721#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000722 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800725#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000726}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200727#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000728
729/*
730 * AES key schedule (decryption)
731 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200732#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100733int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
734 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000735{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800736#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
737 int i, j;
738 uint32_t *SK;
739#endif
740 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000742 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800743
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200744
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000746
Gilles Peskine0de8f852023-03-16 17:14:59 +0100747 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100748 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000749
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200750 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200752 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000754
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200755 ctx->nr = cty.nr;
756
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100757#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
759 mbedtls_aesni_inverse_key((unsigned char *) RK,
760 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200761 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100762 }
763#endif
764
Jerry Yue096da12023-01-10 17:07:01 +0800765#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
766 if (mbedtls_aesce_has_support()) {
767 mbedtls_aesce_inverse_key(
768 (unsigned char *) RK,
769 (const unsigned char *) (cty.buf + cty.rk_offset),
770 ctx->nr);
771 goto exit;
772 }
773#endif
774
Jerry Yu29c91ba2023-08-04 11:02:04 +0800775#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100776 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000777
778 *RK++ = *SK++;
779 *RK++ = *SK++;
780 *RK++ = *SK++;
781 *RK++ = *SK++;
782
Gilles Peskine449bd832023-01-11 14:50:10 +0100783 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
784 for (j = 0; j < 4; j++, SK++) {
785 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
786 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
787 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
788 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000789 }
790 }
791
792 *RK++ = *SK++;
793 *RK++ = *SK++;
794 *RK++ = *SK++;
795 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800796#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200797exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000799
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000801}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100802#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100803
804#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100805static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
806 unsigned int keybits,
807 const unsigned char **key1,
808 unsigned int *key1bits,
809 const unsigned char **key2,
810 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100811{
812 const unsigned int half_keybits = keybits / 2;
813 const unsigned int half_keybytes = half_keybits / 8;
814
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100816 case 256: break;
817 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100819 }
820
821 *key1bits = half_keybits;
822 *key2bits = half_keybits;
823 *key1 = &key[0];
824 *key2 = &key[half_keybytes];
825
826 return 0;
827}
828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
830 const unsigned char *key,
831 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100832{
Janos Follath24eed8d2019-11-22 13:21:35 +0000833 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100834 const unsigned char *key1, *key2;
835 unsigned int key1bits, key2bits;
836
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
838 &key2, &key2bits);
839 if (ret != 0) {
840 return ret;
841 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100842
843 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
845 if (ret != 0) {
846 return ret;
847 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100848
849 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100851}
852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
854 const unsigned char *key,
855 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100856{
Janos Follath24eed8d2019-11-22 13:21:35 +0000857 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100858 const unsigned char *key1, *key2;
859 unsigned int key1bits, key2bits;
860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
862 &key2, &key2bits);
863 if (ret != 0) {
864 return ret;
865 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100866
867 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
869 if (ret != 0) {
870 return ret;
871 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100872
873 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100875}
876#endif /* MBEDTLS_CIPHER_MODE_XTS */
877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100879 do \
880 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
882 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
883 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
884 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100885 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
887 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
888 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
889 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100890 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
892 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
893 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
894 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100895 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
897 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
898 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
899 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
900 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100903 do \
904 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
906 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
907 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
908 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100909 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
911 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
912 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
913 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100914 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100915 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
916 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
917 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
918 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100919 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
921 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
922 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
923 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
924 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000925
926/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200927 * AES-ECB block encryption
928 */
929#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100930int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
931 const unsigned char input[16],
932 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200933{
934 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100935 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200937 uint32_t X[4];
938 uint32_t Y[4];
939 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200940
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
942 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
943 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
944 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200945
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
947 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]);
948 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 +0200949 }
950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 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 +0200952
Gilles Peskine5197c662020-08-26 17:03:24 +0200953 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
955 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
956 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
957 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200958
Gilles Peskine5197c662020-08-26 17:03:24 +0200959 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
961 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200964
Gilles Peskine5197c662020-08-26 17:03:24 +0200965 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
967 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200970
Gilles Peskine5197c662020-08-26 17:03:24 +0200971 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100972 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
973 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
974 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
975 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200976
Gilles Peskine449bd832023-01-11 14:50:10 +0100977 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
978 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
979 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
980 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000981
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200985}
986#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
987
988/*
989 * AES-ECB block decryption
990 */
991#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100992int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
993 const unsigned char input[16],
994 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200995{
996 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100997 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200999 uint32_t X[4];
1000 uint32_t Y[4];
1001 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001002
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1004 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1005 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1006 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001007
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1009 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]);
1010 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 +02001011 }
1012
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 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 +02001014
Gilles Peskine5197c662020-08-26 17:03:24 +02001015 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1017 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1018 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1019 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001020
Gilles Peskine5197c662020-08-26 17:03:24 +02001021 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1023 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001026
Gilles Peskine5197c662020-08-26 17:03:24 +02001027 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1029 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001032
Gilles Peskine5197c662020-08-26 17:03:24 +02001033 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1035 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1036 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1037 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001038
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1040 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1041 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1042 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001043
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001047}
1048#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1049
Gilles Peskine0de8f852023-03-16 17:14:59 +01001050#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001051/* VIA Padlock and our intrinsics-based implementation of AESNI require
1052 * the round keys to be aligned on a 16-byte boundary. We take care of this
1053 * before creating them, but the AES context may have moved (this can happen
1054 * if the library is called from a language with managed memory), and in later
1055 * calls it might have a different alignment with respect to 16-byte memory.
1056 * So we may need to realign.
1057 */
1058static void aes_maybe_realign(mbedtls_aes_context *ctx)
1059{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001060 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1061 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001062 memmove(ctx->buf + new_offset, // new address
1063 ctx->buf + ctx->rk_offset, // current address
1064 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1065 ctx->rk_offset = new_offset;
1066 }
1067}
1068#endif
1069
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001070/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001071 * AES-ECB block encryption/decryption
1072 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001073int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1074 int mode,
1075 const unsigned char input[16],
1076 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001077{
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001079 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001081
Gilles Peskine0de8f852023-03-16 17:14:59 +01001082#if defined(MAY_NEED_TO_ALIGN)
1083 aes_maybe_realign(ctx);
1084#endif
1085
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001086#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1088 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1089 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001090#endif
1091
Jerry Yu2bb3d812023-01-10 17:38:26 +08001092#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1093 if (mbedtls_aesce_has_support()) {
1094 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1095 }
1096#endif
1097
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001100 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001101 }
1102#endif
1103
Jerry Yu29c91ba2023-08-04 11:02:04 +08001104#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 if (mode == MBEDTLS_AES_ENCRYPT) {
1106 return mbedtls_internal_aes_encrypt(ctx, input, output);
1107 } else {
1108 return mbedtls_internal_aes_decrypt(ctx, input, output);
1109 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001110#endif
1111
Paul Bakker5121ce52009-01-03 21:22:43 +00001112}
1113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001115
Paul Bakker5121ce52009-01-03 21:22:43 +00001116/*
1117 * AES-CBC buffer encryption/decryption
1118 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001119int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1120 int mode,
1121 size_t length,
1122 unsigned char iv[16],
1123 const unsigned char *input,
1124 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001125{
Gilles Peskine7820a572021-07-07 21:08:28 +02001126 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001127 unsigned char temp[16];
1128
Gilles Peskine449bd832023-01-11 14:50:10 +01001129 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001130 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 if (length % 16) {
1134 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1135 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001136
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 if (aes_padlock_ace > 0) {
1139 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1140 return 0;
1141 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001142
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001143 // If padlock data misaligned, we just fall back to
1144 // unaccelerated mode
1145 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001146 }
1147#endif
1148
Dave Rodgman906c63c2023-06-14 17:53:51 +01001149 const unsigned char *ivp = iv;
1150
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 if (mode == MBEDTLS_AES_DECRYPT) {
1152 while (length > 0) {
1153 memcpy(temp, input, 16);
1154 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1155 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001156 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001158 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001159 * the result for the next block in CBC, and the cost of transferring that data from
1160 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001161 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001162
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001164
1165 input += 16;
1166 output += 16;
1167 length -= 16;
1168 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 } else {
1170 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001171 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1174 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001175 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001177 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001178
1179 input += 16;
1180 output += 16;
1181 length -= 16;
1182 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001183 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001184 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001185 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001186
Gilles Peskine7820a572021-07-07 21:08:28 +02001187exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001188 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001189}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001190#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001191
Aorimn5f778012016-06-09 23:22:58 +02001192#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001193
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001194typedef unsigned char mbedtls_be128[16];
1195
1196/*
1197 * GF(2^128) multiplication function
1198 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001199 * This function multiplies a field element by x in the polynomial field
1200 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001201 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001202 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001203 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001204#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001205MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001206#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001207static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001208 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001209{
1210 uint64_t a, b, ra, rb;
1211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 a = MBEDTLS_GET_UINT64_LE(x, 0);
1213 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001214
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1216 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001217
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1219 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001220}
1221
Aorimn5f778012016-06-09 23:22:58 +02001222/*
1223 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001224 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001225 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001226 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001227 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001228#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001229MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001230#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001231int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1232 int mode,
1233 size_t length,
1234 const unsigned char data_unit[16],
1235 const unsigned char *input,
1236 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001237{
Janos Follath24eed8d2019-11-22 13:21:35 +00001238 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239 size_t blocks = length / 16;
1240 size_t leftover = length % 16;
1241 unsigned char tweak[16];
1242 unsigned char prev_tweak[16];
1243 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001244
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001246 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001248
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001249 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001251 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 }
Aorimn5f778012016-06-09 23:22:58 +02001253
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001254 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001256 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 }
Aorimn5f778012016-06-09 23:22:58 +02001258
Jaeden Amerod82cd862018-04-28 15:02:45 +01001259 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1261 data_unit, tweak);
1262 if (ret != 0) {
1263 return ret;
1264 }
Aorimn5f778012016-06-09 23:22:58 +02001265
Gilles Peskine449bd832023-01-11 14:50:10 +01001266 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001267 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001268 /* We are on the last block in a decrypt operation that has
1269 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001270 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001271 * the leftovers and then update the current tweak for use on this,
1272 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 memcpy(prev_tweak, tweak, sizeof(tweak));
1274 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275 }
1276
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001278
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1280 if (ret != 0) {
1281 return ret;
1282 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001283
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285
1286 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001288
1289 output += 16;
1290 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001291 }
1292
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001294 /* If we are on the leftover bytes in a decrypt operation, we need to
1295 * use the previous tweak for these bytes (as saved in prev_tweak). */
1296 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001297
Jaeden Amerod82cd862018-04-28 15:02:45 +01001298 /* We are now on the final part of the data unit, which doesn't divide
1299 * evenly by 16. It's time for ciphertext stealing. */
1300 size_t i;
1301 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001302
Jaeden Amerod82cd862018-04-28 15:02:45 +01001303 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001304 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001305 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001306 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001307 }
Aorimn5f778012016-06-09 23:22:58 +02001308
Dave Rodgman069e7f42022-11-24 19:37:26 +00001309 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001311
Jaeden Amerod82cd862018-04-28 15:02:45 +01001312 /* Copy ciphertext bytes from the previous block for input in this
1313 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001315
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1317 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001318 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001319 }
Aorimn5f778012016-06-09 23:22:58 +02001320
Jaeden Amerod82cd862018-04-28 15:02:45 +01001321 /* Write the result back to the previous block, overriding the previous
1322 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001324 }
1325
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001327}
1328#endif /* MBEDTLS_CIPHER_MODE_XTS */
1329
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001330#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001331/*
1332 * AES-CFB128 buffer encryption/decryption
1333 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001334int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1335 int mode,
1336 size_t length,
1337 size_t *iv_off,
1338 unsigned char iv[16],
1339 const unsigned char *input,
1340 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001341{
Paul Bakker27fdf462011-06-09 13:55:13 +00001342 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001343 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001344 size_t n;
1345
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001347 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001349
1350 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001351
Gilles Peskine449bd832023-01-11 14:50:10 +01001352 if (n > 15) {
1353 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1354 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001355
Gilles Peskine449bd832023-01-11 14:50:10 +01001356 if (mode == MBEDTLS_AES_DECRYPT) {
1357 while (length--) {
1358 if (n == 0) {
1359 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1360 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001361 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001363 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001364
1365 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 iv[n] = (unsigned char) c;
1368
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001370 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 } else {
1372 while (length--) {
1373 if (n == 0) {
1374 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1375 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001376 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001378 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001379
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001381
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001383 }
1384 }
1385
1386 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001387 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001388
Gilles Peskine7820a572021-07-07 21:08:28 +02001389exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001390 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001391}
Paul Bakker556efba2014-01-24 15:38:12 +01001392
1393/*
1394 * AES-CFB8 buffer encryption/decryption
1395 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001396int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1397 int mode,
1398 size_t length,
1399 unsigned char iv[16],
1400 const unsigned char *input,
1401 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001402{
Gilles Peskine7820a572021-07-07 21:08:28 +02001403 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001404 unsigned char c;
1405 unsigned char ov[17];
1406
Gilles Peskine449bd832023-01-11 14:50:10 +01001407 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001408 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001409 }
1410 while (length--) {
1411 memcpy(ov, iv, 16);
1412 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1413 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001414 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001415 }
Paul Bakker556efba2014-01-24 15:38:12 +01001416
Gilles Peskine449bd832023-01-11 14:50:10 +01001417 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001418 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 }
Paul Bakker556efba2014-01-24 15:38:12 +01001420
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001422
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001424 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 }
Paul Bakker556efba2014-01-24 15:38:12 +01001426
Gilles Peskine449bd832023-01-11 14:50:10 +01001427 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001428 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001429 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001430
Gilles Peskine7820a572021-07-07 21:08:28 +02001431exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001432 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001433}
Simon Butcher76a5b222018-04-22 22:57:27 +01001434#endif /* MBEDTLS_CIPHER_MODE_CFB */
1435
1436#if defined(MBEDTLS_CIPHER_MODE_OFB)
1437/*
1438 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1439 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001440int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1441 size_t length,
1442 size_t *iv_off,
1443 unsigned char iv[16],
1444 const unsigned char *input,
1445 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001446{
Simon Butcherad4e4932018-04-29 00:43:47 +01001447 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001448 size_t n;
1449
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001450 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001451
Gilles Peskine449bd832023-01-11 14:50:10 +01001452 if (n > 15) {
1453 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1454 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001455
Gilles Peskine449bd832023-01-11 14:50:10 +01001456 while (length--) {
1457 if (n == 0) {
1458 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1459 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001460 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001461 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001462 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001463 *output++ = *input++ ^ iv[n];
1464
Gilles Peskine449bd832023-01-11 14:50:10 +01001465 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001466 }
1467
1468 *iv_off = n;
1469
Simon Butcherad4e4932018-04-29 00:43:47 +01001470exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001471 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001472}
1473#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001475#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001476/*
1477 * AES-CTR buffer encryption/decryption
1478 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001479int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1480 size_t length,
1481 size_t *nc_off,
1482 unsigned char nonce_counter[16],
1483 unsigned char stream_block[16],
1484 const unsigned char *input,
1485 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001486{
Paul Bakker369e14b2012-04-18 14:16:09 +00001487 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001488 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001489 size_t n;
1490
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001491 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001492
Gilles Peskine449bd832023-01-11 14:50:10 +01001493 if (n > 0x0F) {
1494 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1495 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001496
Gilles Peskine449bd832023-01-11 14:50:10 +01001497 while (length--) {
1498 if (n == 0) {
1499 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1500 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001501 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001502 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001503
Gilles Peskine449bd832023-01-11 14:50:10 +01001504 for (i = 16; i > 0; i--) {
1505 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001506 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001507 }
1508 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001509 }
1510 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001511 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001512
Gilles Peskine449bd832023-01-11 14:50:10 +01001513 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001514 }
1515
1516 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001517 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001518
Gilles Peskine7820a572021-07-07 21:08:28 +02001519exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001520 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001521}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001522#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001527/*
1528 * AES test vectors from:
1529 *
1530 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1531 */
Yanray Wang62c99912023-05-11 11:06:53 +08001532static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001533{
1534 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1535 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001536#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001537 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1538 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1539 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1540 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001541#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001542};
1543
Yanray Wang62c99912023-05-11 11:06:53 +08001544static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001545{
1546 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1547 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001548#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001549 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1550 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1551 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1552 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001553#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001554};
1555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001556#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001557static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001558{
1559 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1560 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001561#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001562 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1563 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1564 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1565 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001566#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001567};
1568
Yanray Wang62c99912023-05-11 11:06:53 +08001569static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001570{
1571 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1572 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001573#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001574 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1575 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1576 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1577 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001578#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001579};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001580#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001581
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001582#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001583/*
1584 * AES-CFB128 test vectors from:
1585 *
1586 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1587 */
Yanray Wang62c99912023-05-11 11:06:53 +08001588static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001589{
1590 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1591 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001592#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001593 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1594 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1595 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1596 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1597 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1598 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1599 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001600#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001601};
1602
1603static const unsigned char aes_test_cfb128_iv[16] =
1604{
1605 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1606 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1607};
1608
1609static const unsigned char aes_test_cfb128_pt[64] =
1610{
1611 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1612 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1613 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1614 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1615 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1616 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1617 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1618 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1619};
1620
Yanray Wang62c99912023-05-11 11:06:53 +08001621static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001622{
1623 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1624 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1625 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1626 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1627 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1628 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1629 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1630 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001631#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001632 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1633 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1634 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1635 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1636 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1637 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1638 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1639 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1640 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1641 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1642 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1643 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1644 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1645 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1646 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1647 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001648#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001649};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001650#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001651
Simon Butcherad4e4932018-04-29 00:43:47 +01001652#if defined(MBEDTLS_CIPHER_MODE_OFB)
1653/*
1654 * AES-OFB test vectors from:
1655 *
Simon Butcher5db13622018-06-04 22:11:25 +01001656 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001657 */
Yanray Wang62c99912023-05-11 11:06:53 +08001658static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001659{
1660 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1661 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001662#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001663 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1664 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1665 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1666 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1667 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1668 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1669 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001670#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001671};
1672
1673static const unsigned char aes_test_ofb_iv[16] =
1674{
1675 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1676 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1677};
1678
1679static const unsigned char aes_test_ofb_pt[64] =
1680{
1681 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1682 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1683 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1684 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1685 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1686 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1687 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1688 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1689};
1690
Yanray Wang62c99912023-05-11 11:06:53 +08001691static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001692{
1693 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1694 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1695 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1696 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1697 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1698 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1699 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1700 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001701#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001702 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1703 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1704 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1705 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1706 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1707 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1708 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1709 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1710 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1711 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1712 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1713 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1714 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1715 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1716 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1717 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001718#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001719};
1720#endif /* MBEDTLS_CIPHER_MODE_OFB */
1721
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001722#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001723/*
1724 * AES-CTR test vectors from:
1725 *
1726 * http://www.faqs.org/rfcs/rfc3686.html
1727 */
1728
Yanray Wang62c99912023-05-11 11:06:53 +08001729static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001730{
1731 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1732 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1733 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1734 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1735 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1736 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1737};
1738
Yanray Wang62c99912023-05-11 11:06:53 +08001739static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001740{
1741 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1743 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1744 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1745 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1746 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1747};
1748
Yanray Wang62c99912023-05-11 11:06:53 +08001749static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001750{
1751 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1752 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001753 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1754 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1755 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1756 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1757
1758 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1759 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1760 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1761 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1762 0x20, 0x21, 0x22, 0x23 }
1763};
1764
Yanray Wang62c99912023-05-11 11:06:53 +08001765static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001766{
1767 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1768 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1769 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1770 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1771 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1772 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1773 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1774 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1775 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1776 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1777 0x25, 0xB2, 0x07, 0x2F }
1778};
1779
1780static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001781{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001782#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001783
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001784#if defined(MBEDTLS_CIPHER_MODE_XTS)
1785/*
1786 * AES-XTS test vectors from:
1787 *
1788 * IEEE P1619/D16 Annex B
1789 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1790 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1791 */
1792static const unsigned char aes_test_xts_key[][32] =
1793{
1794 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1798 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1799 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1800 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1801 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1802 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1803 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1804 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1805 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1806};
1807
1808static const unsigned char aes_test_xts_pt32[][32] =
1809{
1810 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1821 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1822};
1823
1824static const unsigned char aes_test_xts_ct32[][32] =
1825{
1826 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1827 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1828 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1829 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1830 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1831 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1832 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1833 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1834 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1835 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1836 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1837 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1838};
1839
1840static const unsigned char aes_test_xts_data_unit[][16] =
1841{
Gilles Peskine449bd832023-01-11 14:50:10 +01001842 { 0x00, 0x00, 0x00, 0x00, 0x00, 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 },
1846 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001848};
1849
1850#endif /* MBEDTLS_CIPHER_MODE_XTS */
1851
Paul Bakker5121ce52009-01-03 21:22:43 +00001852/*
1853 * Checkup routine
1854 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001855int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001856{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001857 int ret = 0, i, j, u, mode;
1858 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001859 unsigned char key[32];
1860 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001861 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001862#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1863 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001864 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001865#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001866#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001867 unsigned char prv[16];
1868#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001869#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1870 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001871 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001872#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001873#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001874 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001875#endif
1876#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001877 unsigned char nonce_counter[16];
1878 unsigned char stream_block[16];
1879#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001881
Gilles Peskine449bd832023-01-11 14:50:10 +01001882 memset(key, 0, 32);
1883 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001884
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001885 if (verbose != 0) {
1886#if defined(MBEDTLS_AES_ALT)
1887 mbedtls_printf(" AES note: alternative implementation.\n");
1888#else /* MBEDTLS_AES_ALT */
1889#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1890 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1891 mbedtls_printf(" AES note: using VIA Padlock.\n");
1892 } else
1893#endif
1894#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001895#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001896 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001897#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001898 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001899#else
1900#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1901#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001902 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1903 mbedtls_printf(" AES note: using AESNI.\n");
1904 } else
1905#endif
1906#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1907 if (mbedtls_aesce_has_support()) {
1908 mbedtls_printf(" AES note: using AESCE.\n");
1909 } else
1910#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001911 {
1912#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1913 mbedtls_printf(" AES note: built-in implementation.\n");
1914#endif
1915 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001916#endif /* MBEDTLS_AES_ALT */
1917 }
1918
Paul Bakker5121ce52009-01-03 21:22:43 +00001919 /*
1920 * ECB mode
1921 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001922 {
1923 static const int num_tests =
1924 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001925
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001926 for (i = 0; i < num_tests << 1; i++) {
1927 u = i >> 1;
1928 keybits = 128 + u * 64;
1929 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001930
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001931 if (verbose != 0) {
1932 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1933 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1934 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001935
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001936 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001937
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001938 if (mode == MBEDTLS_AES_DECRYPT) {
1939 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1940 aes_tests = aes_test_ecb_dec[u];
1941 } else {
1942 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1943 aes_tests = aes_test_ecb_enc[u];
1944 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001945
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001946 /*
1947 * AES-192 is an optional feature that may be unavailable when
1948 * there is an alternative underlying implementation i.e. when
1949 * MBEDTLS_AES_ALT is defined.
1950 */
1951 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1952 mbedtls_printf("skipped\n");
1953 continue;
1954 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001955 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001956 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001957
1958 for (j = 0; j < 10000; j++) {
1959 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1960 if (ret != 0) {
1961 goto exit;
1962 }
1963 }
1964
1965 if (memcmp(buf, aes_tests, 16) != 0) {
1966 ret = 1;
1967 goto exit;
1968 }
1969
1970 if (verbose != 0) {
1971 mbedtls_printf("passed\n");
1972 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001973 }
1974
Gilles Peskine449bd832023-01-11 14:50:10 +01001975 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001976 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001977 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001978 }
1979
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001980#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001981 /*
1982 * CBC mode
1983 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001984 {
1985 static const int num_tests =
1986 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001987
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001988 for (i = 0; i < num_tests << 1; i++) {
1989 u = i >> 1;
1990 keybits = 128 + u * 64;
1991 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001992
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001993 if (verbose != 0) {
1994 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1995 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001996 }
1997
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001998 memset(iv, 0, 16);
1999 memset(prv, 0, 16);
2000 memset(buf, 0, 16);
2001
2002 if (mode == MBEDTLS_AES_DECRYPT) {
2003 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2004 aes_tests = aes_test_cbc_dec[u];
2005 } else {
2006 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2007 aes_tests = aes_test_cbc_enc[u];
2008 }
2009
2010 /*
2011 * AES-192 is an optional feature that may be unavailable when
2012 * there is an alternative underlying implementation i.e. when
2013 * MBEDTLS_AES_ALT is defined.
2014 */
2015 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2016 mbedtls_printf("skipped\n");
2017 continue;
2018 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002019 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002020 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002021
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002022 for (j = 0; j < 10000; j++) {
2023 if (mode == MBEDTLS_AES_ENCRYPT) {
2024 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002025
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002026 memcpy(tmp, prv, 16);
2027 memcpy(prv, buf, 16);
2028 memcpy(buf, tmp, 16);
2029 }
2030
2031 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2032 if (ret != 0) {
2033 goto exit;
2034 }
2035
2036 }
2037
2038 if (memcmp(buf, aes_tests, 16) != 0) {
2039 ret = 1;
2040 goto exit;
2041 }
2042
2043 if (verbose != 0) {
2044 mbedtls_printf("passed\n");
2045 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002046 }
2047
Gilles Peskine449bd832023-01-11 14:50:10 +01002048 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002049 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002050 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002051 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002052#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002053
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002054#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002055 /*
2056 * CFB128 mode
2057 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002058 {
2059 static const int num_tests =
2060 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002061
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002062 for (i = 0; i < num_tests << 1; i++) {
2063 u = i >> 1;
2064 keybits = 128 + u * 64;
2065 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002066
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002067 if (verbose != 0) {
2068 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2069 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2070 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002071
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002072 memcpy(iv, aes_test_cfb128_iv, 16);
2073 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002074
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002075 offset = 0;
2076 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2077 /*
2078 * AES-192 is an optional feature that may be unavailable when
2079 * there is an alternative underlying implementation i.e. when
2080 * MBEDTLS_AES_ALT is defined.
2081 */
2082 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2083 mbedtls_printf("skipped\n");
2084 continue;
2085 } else if (ret != 0) {
2086 goto exit;
2087 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002089 if (mode == MBEDTLS_AES_DECRYPT) {
2090 memcpy(buf, aes_test_cfb128_ct[u], 64);
2091 aes_tests = aes_test_cfb128_pt;
2092 } else {
2093 memcpy(buf, aes_test_cfb128_pt, 64);
2094 aes_tests = aes_test_cfb128_ct[u];
2095 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002096
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002097 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2098 if (ret != 0) {
2099 goto exit;
2100 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002101
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002102 if (memcmp(buf, aes_tests, 64) != 0) {
2103 ret = 1;
2104 goto exit;
2105 }
2106
2107 if (verbose != 0) {
2108 mbedtls_printf("passed\n");
2109 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002110 }
2111
Gilles Peskine449bd832023-01-11 14:50:10 +01002112 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002113 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002114 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002115 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002116#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002117
Simon Butcherad4e4932018-04-29 00:43:47 +01002118#if defined(MBEDTLS_CIPHER_MODE_OFB)
2119 /*
2120 * OFB mode
2121 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002122 {
2123 static const int num_tests =
2124 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002125
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002126 for (i = 0; i < num_tests << 1; i++) {
2127 u = i >> 1;
2128 keybits = 128 + u * 64;
2129 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002130
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002131 if (verbose != 0) {
2132 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2133 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2134 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002135
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002136 memcpy(iv, aes_test_ofb_iv, 16);
2137 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002138
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002139 offset = 0;
2140 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2141 /*
2142 * AES-192 is an optional feature that may be unavailable when
2143 * there is an alternative underlying implementation i.e. when
2144 * MBEDTLS_AES_ALT is defined.
2145 */
2146 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2147 mbedtls_printf("skipped\n");
2148 continue;
2149 } else if (ret != 0) {
2150 goto exit;
2151 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002152
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002153 if (mode == MBEDTLS_AES_DECRYPT) {
2154 memcpy(buf, aes_test_ofb_ct[u], 64);
2155 aes_tests = aes_test_ofb_pt;
2156 } else {
2157 memcpy(buf, aes_test_ofb_pt, 64);
2158 aes_tests = aes_test_ofb_ct[u];
2159 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002160
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002161 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2162 if (ret != 0) {
2163 goto exit;
2164 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002165
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002166 if (memcmp(buf, aes_tests, 64) != 0) {
2167 ret = 1;
2168 goto exit;
2169 }
2170
2171 if (verbose != 0) {
2172 mbedtls_printf("passed\n");
2173 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002174 }
2175
Gilles Peskine449bd832023-01-11 14:50:10 +01002176 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002177 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002178 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002179 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002180#endif /* MBEDTLS_CIPHER_MODE_OFB */
2181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002182#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002183 /*
2184 * CTR mode
2185 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002186 {
2187 static const int num_tests =
2188 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002189
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002190 for (i = 0; i < num_tests << 1; i++) {
2191 u = i >> 1;
2192 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002193
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002194 if (verbose != 0) {
2195 mbedtls_printf(" AES-CTR-128 (%s): ",
2196 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2197 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002198
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002199 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2200 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002201
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002202 offset = 0;
2203 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2204 goto exit;
2205 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002206
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002207 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002208
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002209 if (mode == MBEDTLS_AES_DECRYPT) {
2210 memcpy(buf, aes_test_ctr_ct[u], len);
2211 aes_tests = aes_test_ctr_pt[u];
2212 } else {
2213 memcpy(buf, aes_test_ctr_pt[u], len);
2214 aes_tests = aes_test_ctr_ct[u];
2215 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002216
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002217 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2218 stream_block, buf, buf);
2219 if (ret != 0) {
2220 goto exit;
2221 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002222
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002223 if (memcmp(buf, aes_tests, len) != 0) {
2224 ret = 1;
2225 goto exit;
2226 }
2227
2228 if (verbose != 0) {
2229 mbedtls_printf("passed\n");
2230 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002231 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002232 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002233
Gilles Peskine449bd832023-01-11 14:50:10 +01002234 if (verbose != 0) {
2235 mbedtls_printf("\n");
2236 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002237#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002238
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002239#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002240 /*
2241 * XTS mode
2242 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002243 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002244 static const int num_tests =
2245 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2246 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002247
Gilles Peskine449bd832023-01-11 14:50:10 +01002248 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002249
Gilles Peskine449bd832023-01-11 14:50:10 +01002250 for (i = 0; i < num_tests << 1; i++) {
2251 const unsigned char *data_unit;
2252 u = i >> 1;
2253 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002254
Gilles Peskine449bd832023-01-11 14:50:10 +01002255 if (verbose != 0) {
2256 mbedtls_printf(" AES-XTS-128 (%s): ",
2257 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2258 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002259
Gilles Peskine449bd832023-01-11 14:50:10 +01002260 memset(key, 0, sizeof(key));
2261 memcpy(key, aes_test_xts_key[u], 32);
2262 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002263
Gilles Peskine449bd832023-01-11 14:50:10 +01002264 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002265
Gilles Peskine449bd832023-01-11 14:50:10 +01002266 if (mode == MBEDTLS_AES_DECRYPT) {
2267 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2268 if (ret != 0) {
2269 goto exit;
2270 }
2271 memcpy(buf, aes_test_xts_ct32[u], len);
2272 aes_tests = aes_test_xts_pt32[u];
2273 } else {
2274 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2275 if (ret != 0) {
2276 goto exit;
2277 }
2278 memcpy(buf, aes_test_xts_pt32[u], len);
2279 aes_tests = aes_test_xts_ct32[u];
2280 }
2281
2282
2283 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2284 buf, buf);
2285 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002286 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002287 }
2288
2289 if (memcmp(buf, aes_tests, len) != 0) {
2290 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002291 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002292 }
2293
2294 if (verbose != 0) {
2295 mbedtls_printf("passed\n");
2296 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002297 }
2298
Gilles Peskine449bd832023-01-11 14:50:10 +01002299 if (verbose != 0) {
2300 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002301 }
2302
Gilles Peskine449bd832023-01-11 14:50:10 +01002303 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002304 }
2305#endif /* MBEDTLS_CIPHER_MODE_XTS */
2306
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002307 ret = 0;
2308
2309exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002310 if (ret != 0 && verbose != 0) {
2311 mbedtls_printf("failed\n");
2312 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002313
Gilles Peskine449bd832023-01-11 14:50:10 +01002314 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002315
Gilles Peskine449bd832023-01-11 14:50:10 +01002316 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002317}
2318
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002319#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002321#endif /* MBEDTLS_AES_C */