blob: 8afa7a65d328c413bf960d10a5caba6997c47bd3 [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
37#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
38 defined(__aarch64__) && !defined(MBEDTLS_HAVE_ARM64)
39#define MBEDTLS_HAVE_ARM64
40#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080041#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080042#endif
43#endif
44
45#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && \
46 (defined(__amd64__) || defined(__x86_64__)) && \
47 !defined(MBEDTLS_HAVE_X86_64)
48#define MBEDTLS_HAVE_X86_64
49#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080050#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080051#endif
52#endif
53
54#if defined(MBEDTLS_HAVE_ASM) && defined(__GNUC__) && defined(__i386__) && \
55 !defined(MBEDTLS_HAVE_ASAN)
56#define MBEDTLS_HAVE_X86
57
58#if !defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080059#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080060#endif
61#endif
62
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000064#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000065#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000067#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010068#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080069#if defined(MBEDTLS_AESCE_C)
70#include "aesce.h"
71#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000072
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000073#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010074
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020076
Gilles Peskine0f454e42023-03-16 14:58:46 +010077#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000078static int aes_padlock_ace = -1;
79#endif
80
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000082/*
83 * Forward S-box
84 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010085#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
86 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000087static const unsigned char FSb[256] =
88{
89 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
90 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
91 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
92 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
93 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
94 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
95 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
96 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
97 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
98 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
99 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
100 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
101 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
102 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
103 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
104 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
105 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
106 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
107 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
108 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
109 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
110 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
111 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
112 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
113 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
114 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
115 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
116 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
117 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
118 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
119 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
120 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
121};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100122#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
123 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000124
125/*
126 * Forward tables
127 */
128#define FT \
129\
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
131 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
132 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
133 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
134 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
135 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
136 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
137 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
138 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
139 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
140 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
141 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
142 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
143 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
144 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
145 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
146 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
147 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
148 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
149 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
150 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
151 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
152 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
153 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
154 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
155 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
156 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
157 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
158 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
159 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
160 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
161 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
162 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
163 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
164 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
165 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
166 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
167 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
168 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
169 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
170 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
171 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
172 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
173 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
174 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
175 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
176 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
177 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
178 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
179 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
180 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
181 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
182 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
183 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
184 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
185 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
186 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
187 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
188 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
189 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
190 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
191 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
192 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
193 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 +0000194
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100195#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100196#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000197static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000198#undef V
199
Hanno Beckerad049a92017-06-19 16:31:54 +0100200#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000203static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000204#undef V
205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000207static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000208#undef V
209
Gilles Peskine449bd832023-01-11 14:50:10 +0100210#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000211static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000212#undef V
213
Hanno Becker177d3cf2017-06-07 15:52:48 +0100214#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200215
Dave Rodgman1be24632023-06-29 12:01:24 +0100216#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
217
Paul Bakker5121ce52009-01-03 21:22:43 +0000218#undef FT
219
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100220#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000221/*
222 * Reverse S-box
223 */
224static const unsigned char RSb[256] =
225{
226 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
227 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
228 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
229 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
230 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
231 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
232 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
233 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
234 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
235 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
236 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
237 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
238 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
239 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
240 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
241 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
242 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
243 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
244 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
245 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
246 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
247 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
248 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
249 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
250 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
251 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
252 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
253 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
254 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
255 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
256 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
257 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
258};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100259#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
261/*
262 * Reverse tables
263 */
264#define RT \
265\
Gilles Peskine449bd832023-01-11 14:50:10 +0100266 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
267 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
268 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
269 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
270 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
271 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
272 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
273 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
274 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
275 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
276 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
277 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
278 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
279 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
280 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
281 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
282 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
283 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
284 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
285 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
286 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
287 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
288 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
289 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
290 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
291 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
292 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
293 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
294 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
295 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
296 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
297 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
298 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
299 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
300 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
301 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
302 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
303 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
304 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
305 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
306 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
307 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
308 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
309 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
310 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
311 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
312 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
313 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
314 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
315 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
316 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
317 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
318 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
319 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
320 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
321 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
322 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
323 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
324 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
325 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
326 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
327 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
328 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
329 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 +0000330
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100331#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000335#undef V
336
Hanno Beckerad049a92017-06-19 16:31:54 +0100337#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000340static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000341#undef V
342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000344static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000345#undef V
346
Gilles Peskine449bd832023-01-11 14:50:10 +0100347#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000349#undef V
350
Hanno Becker177d3cf2017-06-07 15:52:48 +0100351#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200352
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800353#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
354
Paul Bakker5121ce52009-01-03 21:22:43 +0000355#undef RT
356
Dave Rodgman34152a42023-06-27 18:31:24 +0100357#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000358/*
359 * Round constants
360 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000361static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000362{
363 0x00000001, 0x00000002, 0x00000004, 0x00000008,
364 0x00000010, 0x00000020, 0x00000040, 0x00000080,
365 0x0000001B, 0x00000036
366};
Dave Rodgman34152a42023-06-27 18:31:24 +0100367#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000368
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
371/*
372 * Forward S-box & tables
373 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100374#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
375 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000376static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100377#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
378 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100379#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200380static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100381#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200382static uint32_t FT1[256];
383static uint32_t FT2[256];
384static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100385#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100386#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
388/*
389 * Reverse S-box & tables
390 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100391#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000392static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100393#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100394
395#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000396static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100397#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000398static uint32_t RT1[256];
399static uint32_t RT2[256];
400static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100401#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100402#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
Dave Rodgman8c753f92023-06-27 18:16:13 +0100404#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000405/*
406 * Round constants
407 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000408static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410/*
411 * Tables generation code
412 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100413#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
414#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
415#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
417static int aes_init_done = 0;
418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000420{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800421 int i;
422 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800423 uint8_t pow[256];
424 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
426 /*
427 * compute pow and log tables over GF(2^8)
428 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800431 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800432 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000433 }
434
435 /*
436 * calculate the round constants
437 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800439 RCON[i] = x;
440 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 }
442
443 /*
444 * generate the forward and reverse S-boxes
445 */
446 FSb[0x00] = 0x63;
447 RSb[0x63] = 0x00;
448
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 x = pow[255 - log[i]];
451
Yanray Wangfe944ce2023-06-26 18:16:01 +0800452 y = x; y = (y << 1) | (y >> 7);
453 x ^= y; y = (y << 1) | (y >> 7);
454 x ^= y; y = (y << 1) | (y >> 7);
455 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 x ^= y ^ 0x63;
457
Yanray Wangfe944ce2023-06-26 18:16:01 +0800458 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000459 RSb[x] = (unsigned char) i;
460 }
461
462 /*
463 * generate the forward and reverse tables
464 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800467 y = XTIME(x);
468 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Gilles Peskine449bd832023-01-11 14:50:10 +0100470 FT0[i] = ((uint32_t) y) ^
471 ((uint32_t) x << 8) ^
472 ((uint32_t) x << 16) ^
473 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
Hanno Beckerad049a92017-06-19 16:31:54 +0100475#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 FT1[i] = ROTL8(FT0[i]);
477 FT2[i] = ROTL8(FT1[i]);
478 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100479#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 x = RSb[i];
482
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100483#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
485 ((uint32_t) MUL(0x09, x) << 8) ^
486 ((uint32_t) MUL(0x0D, x) << 16) ^
487 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000488
Hanno Beckerad049a92017-06-19 16:31:54 +0100489#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 RT1[i] = ROTL8(RT0[i]);
491 RT2[i] = ROTL8(RT1[i]);
492 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100493#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100494#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 }
496}
497
Dave Rodgman8c753f92023-06-27 18:16:13 +0100498#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
499
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200500#undef ROTL8
501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000503
Hanno Beckerad049a92017-06-19 16:31:54 +0100504#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
507#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
508#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200509
510#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100511#define AES_RT1(idx) ROTL8(RT0[idx])
512#define AES_RT2(idx) ROTL16(RT0[idx])
513#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200514
515#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100516#define AES_FT1(idx) ROTL8(FT0[idx])
517#define AES_FT2(idx) ROTL16(FT0[idx])
518#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200519
Hanno Becker177d3cf2017-06-07 15:52:48 +0100520#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200521
522#define AES_RT0(idx) RT0[idx]
523#define AES_RT1(idx) RT1[idx]
524#define AES_RT2(idx) RT2[idx]
525#define AES_RT3(idx) RT3[idx]
526
527#define AES_FT0(idx) FT0[idx]
528#define AES_FT1(idx) FT1[idx]
529#define AES_FT2(idx) FT2[idx]
530#define AES_FT3(idx) FT3[idx]
531
Hanno Becker177d3cf2017-06-07 15:52:48 +0100532#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200535{
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200537}
538
Gilles Peskine449bd832023-01-11 14:50:10 +0100539void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200540{
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200542 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200546}
547
Jaeden Amero9366feb2018-05-29 18:55:17 +0100548#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100549void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100550{
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 mbedtls_aes_init(&ctx->crypt);
552 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100553}
554
Gilles Peskine449bd832023-01-11 14:50:10 +0100555void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100556{
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100558 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 }
Simon Butcher5201e412018-12-06 17:40:14 +0000560
Gilles Peskine449bd832023-01-11 14:50:10 +0100561 mbedtls_aes_free(&ctx->crypt);
562 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100563}
564#endif /* MBEDTLS_CIPHER_MODE_XTS */
565
Gilles Peskine0de8f852023-03-16 17:14:59 +0100566/* Some implementations need the round keys to be aligned.
567 * Return an offset to be added to buf, such that (buf + offset) is
568 * correctly aligned.
569 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
570 * i.e. an offset of 1 means 4 bytes and so on.
571 */
572#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100573 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100574#define MAY_NEED_TO_ALIGN
575#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100576
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100577#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
578 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100579static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
580{
581#if defined(MAY_NEED_TO_ALIGN)
582 int align_16_bytes = 0;
583
584#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
585 if (aes_padlock_ace == -1) {
586 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
587 }
588 if (aes_padlock_ace) {
589 align_16_bytes = 1;
590 }
591#endif
592
Gilles Peskine9c682e72023-03-16 17:21:33 +0100593#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100594 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
595 align_16_bytes = 1;
596 }
597#endif
598
599 if (align_16_bytes) {
600 /* These implementations needs 16-byte alignment
601 * for the round key array. */
602 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
603 if (delta == 0) {
604 return 0;
605 } else {
606 return 4 - delta; // 16 bytes = 4 uint32_t
607 }
608 }
609#else /* MAY_NEED_TO_ALIGN */
610 (void) buf;
611#endif /* MAY_NEED_TO_ALIGN */
612
613 return 0;
614}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100615#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
616 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100617
Paul Bakker5121ce52009-01-03 21:22:43 +0000618/*
619 * AES key schedule (encryption)
620 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200621#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100622int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
623 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000624{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800625#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Paul Bakker23986e52011-04-24 08:57:21 +0000626 unsigned int i;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800627#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000628 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800632#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 case 192: ctx->nr = 12; break;
634 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800635#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 }
638
Simon Butcher5201e412018-12-06 17:40:14 +0000639#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000641 aes_gen_tables();
642 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000643 }
644#endif
645
Gilles Peskine0de8f852023-03-16 17:14:59 +0100646 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100647 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100649#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
651 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
652 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100653#endif
654
Jerry Yu3f2fb712023-01-10 17:05:42 +0800655#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
656 if (mbedtls_aesce_has_support()) {
657 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
658 }
659#endif
660
Jerry Yu29c91ba2023-08-04 11:02:04 +0800661#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 for (i = 0; i < (keybits >> 5); i++) {
663 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 }
665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 case 10:
668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
672 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
673 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
674 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
676 RK[5] = RK[1] ^ RK[4];
677 RK[6] = RK[2] ^ RK[5];
678 RK[7] = RK[3] ^ RK[6];
679 }
680 break;
681
Arto Kinnunen732ca322023-04-14 14:26:10 +0800682#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 case 12:
684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000686 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
688 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
689 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
690 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
692 RK[7] = RK[1] ^ RK[6];
693 RK[8] = RK[2] ^ RK[7];
694 RK[9] = RK[3] ^ RK[8];
695 RK[10] = RK[4] ^ RK[9];
696 RK[11] = RK[5] ^ RK[10];
697 }
698 break;
699
700 case 14:
701
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
705 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
706 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
707 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
709 RK[9] = RK[1] ^ RK[8];
710 RK[10] = RK[2] ^ RK[9];
711 RK[11] = RK[3] ^ RK[10];
712
713 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
715 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
716 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
717 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000718
719 RK[13] = RK[5] ^ RK[12];
720 RK[14] = RK[6] ^ RK[13];
721 RK[15] = RK[7] ^ RK[14];
722 }
723 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800724#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000725 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800728#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000729}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200730#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
732/*
733 * AES key schedule (decryption)
734 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200735#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100736int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
737 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000738{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800739#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
740 int i, j;
741 uint32_t *SK;
742#endif
743 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200744 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000745 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800746
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200747
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000749
Gilles Peskine0de8f852023-03-16 17:14:59 +0100750 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100751 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000752
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200753 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200755 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000757
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200758 ctx->nr = cty.nr;
759
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100760#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
762 mbedtls_aesni_inverse_key((unsigned char *) RK,
763 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200764 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100765 }
766#endif
767
Jerry Yue096da12023-01-10 17:07:01 +0800768#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
769 if (mbedtls_aesce_has_support()) {
770 mbedtls_aesce_inverse_key(
771 (unsigned char *) RK,
772 (const unsigned char *) (cty.buf + cty.rk_offset),
773 ctx->nr);
774 goto exit;
775 }
776#endif
777
Jerry Yu29c91ba2023-08-04 11:02:04 +0800778#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100779 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
781 *RK++ = *SK++;
782 *RK++ = *SK++;
783 *RK++ = *SK++;
784 *RK++ = *SK++;
785
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
787 for (j = 0; j < 4; j++, SK++) {
788 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
789 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
790 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
791 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 }
793 }
794
795 *RK++ = *SK++;
796 *RK++ = *SK++;
797 *RK++ = *SK++;
798 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800799#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200800exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000804}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100805#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100806
807#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100808static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
809 unsigned int keybits,
810 const unsigned char **key1,
811 unsigned int *key1bits,
812 const unsigned char **key2,
813 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100814{
815 const unsigned int half_keybits = keybits / 2;
816 const unsigned int half_keybytes = half_keybits / 8;
817
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100819 case 256: break;
820 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100822 }
823
824 *key1bits = half_keybits;
825 *key2bits = half_keybits;
826 *key1 = &key[0];
827 *key2 = &key[half_keybytes];
828
829 return 0;
830}
831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
833 const unsigned char *key,
834 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100835{
Janos Follath24eed8d2019-11-22 13:21:35 +0000836 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100837 const unsigned char *key1, *key2;
838 unsigned int key1bits, key2bits;
839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
841 &key2, &key2bits);
842 if (ret != 0) {
843 return ret;
844 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100845
846 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
848 if (ret != 0) {
849 return ret;
850 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100851
852 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100854}
855
Gilles Peskine449bd832023-01-11 14:50:10 +0100856int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
857 const unsigned char *key,
858 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100859{
Janos Follath24eed8d2019-11-22 13:21:35 +0000860 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100861 const unsigned char *key1, *key2;
862 unsigned int key1bits, key2bits;
863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
865 &key2, &key2bits);
866 if (ret != 0) {
867 return ret;
868 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100869
870 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
872 if (ret != 0) {
873 return ret;
874 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100875
876 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100878}
879#endif /* MBEDTLS_CIPHER_MODE_XTS */
880
Gilles Peskine449bd832023-01-11 14:50:10 +0100881#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100882 do \
883 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
885 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
886 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
887 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100888 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
890 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
891 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
892 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100893 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
895 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
896 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
897 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100898 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
900 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
901 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
902 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
903 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000904
Gilles Peskine449bd832023-01-11 14:50:10 +0100905#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100906 do \
907 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
909 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
910 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
911 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100912 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
914 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
915 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
916 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100917 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
919 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
920 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
921 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100922 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
924 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
925 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
926 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
927 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000928
929/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930 * AES-ECB block encryption
931 */
932#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100933int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
934 const unsigned char input[16],
935 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936{
937 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100938 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200940 uint32_t X[4];
941 uint32_t Y[4];
942 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
945 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
946 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
947 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
950 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]);
951 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 +0200952 }
953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 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 +0200955
Gilles Peskine5197c662020-08-26 17:03:24 +0200956 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
958 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
959 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
960 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200961
Gilles Peskine5197c662020-08-26 17:03:24 +0200962 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
965 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
966 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Gilles Peskine5197c662020-08-26 17:03:24 +0200968 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
971 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
972 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Gilles Peskine5197c662020-08-26 17:03:24 +0200974 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
977 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
978 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
981 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
982 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
983 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500986
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200988}
989#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
990
991/*
992 * AES-ECB block decryption
993 */
994#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100995int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
996 const unsigned char input[16],
997 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998{
999 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +01001000 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001002 uint32_t X[4];
1003 uint32_t Y[4];
1004 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1007 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1008 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1009 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1012 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]);
1013 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 +02001014 }
1015
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 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 +02001017
Gilles Peskine5197c662020-08-26 17:03:24 +02001018 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1020 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1021 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1022 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001023
Gilles Peskine5197c662020-08-26 17:03:24 +02001024 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1027 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1028 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001029
Gilles Peskine5197c662020-08-26 17:03:24 +02001030 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1033 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1034 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001035
Gilles Peskine5197c662020-08-26 17:03:24 +02001036 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1039 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1040 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001041
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1043 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1044 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1045 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001046
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001048
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001050}
1051#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1052
Gilles Peskine0de8f852023-03-16 17:14:59 +01001053#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001054/* VIA Padlock and our intrinsics-based implementation of AESNI require
1055 * the round keys to be aligned on a 16-byte boundary. We take care of this
1056 * before creating them, but the AES context may have moved (this can happen
1057 * if the library is called from a language with managed memory), and in later
1058 * calls it might have a different alignment with respect to 16-byte memory.
1059 * So we may need to realign.
1060 */
1061static void aes_maybe_realign(mbedtls_aes_context *ctx)
1062{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001063 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1064 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001065 memmove(ctx->buf + new_offset, // new address
1066 ctx->buf + ctx->rk_offset, // current address
1067 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1068 ctx->rk_offset = new_offset;
1069 }
1070}
1071#endif
1072
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001073/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001074 * AES-ECB block encryption/decryption
1075 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001076int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1077 int mode,
1078 const unsigned char input[16],
1079 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001080{
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001082 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001084
Gilles Peskine0de8f852023-03-16 17:14:59 +01001085#if defined(MAY_NEED_TO_ALIGN)
1086 aes_maybe_realign(ctx);
1087#endif
1088
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001089#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001090 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1091 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1092 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001093#endif
1094
Jerry Yu2bb3d812023-01-10 17:38:26 +08001095#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1096 if (mbedtls_aesce_has_support()) {
1097 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1098 }
1099#endif
1100
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001103 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001104 }
1105#endif
1106
Jerry Yu29c91ba2023-08-04 11:02:04 +08001107#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 if (mode == MBEDTLS_AES_ENCRYPT) {
1109 return mbedtls_internal_aes_encrypt(ctx, input, output);
1110 } else {
1111 return mbedtls_internal_aes_decrypt(ctx, input, output);
1112 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001113#endif
1114
Paul Bakker5121ce52009-01-03 21:22:43 +00001115}
1116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001118
Paul Bakker5121ce52009-01-03 21:22:43 +00001119/*
1120 * AES-CBC buffer encryption/decryption
1121 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001122int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1123 int mode,
1124 size_t length,
1125 unsigned char iv[16],
1126 const unsigned char *input,
1127 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001128{
Gilles Peskine7820a572021-07-07 21:08:28 +02001129 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001130 unsigned char temp[16];
1131
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001133 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001135
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 if (length % 16) {
1137 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1138 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001139
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 if (aes_padlock_ace > 0) {
1142 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1143 return 0;
1144 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001145
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001146 // If padlock data misaligned, we just fall back to
1147 // unaccelerated mode
1148 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001149 }
1150#endif
1151
Dave Rodgman906c63c2023-06-14 17:53:51 +01001152 const unsigned char *ivp = iv;
1153
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 if (mode == MBEDTLS_AES_DECRYPT) {
1155 while (length > 0) {
1156 memcpy(temp, input, 16);
1157 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1158 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001159 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001161 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001162 * the result for the next block in CBC, and the cost of transferring that data from
1163 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001164 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001165
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001167
1168 input += 16;
1169 output += 16;
1170 length -= 16;
1171 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 } else {
1173 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001174 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1177 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001178 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001180 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001181
1182 input += 16;
1183 output += 16;
1184 length -= 16;
1185 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001186 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001187 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001188 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001189
Gilles Peskine7820a572021-07-07 21:08:28 +02001190exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001192}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001194
Aorimn5f778012016-06-09 23:22:58 +02001195#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001196
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001197typedef unsigned char mbedtls_be128[16];
1198
1199/*
1200 * GF(2^128) multiplication function
1201 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001202 * This function multiplies a field element by x in the polynomial field
1203 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001204 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001205 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001206 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001207#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001208MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001209#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001210static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001211 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001212{
1213 uint64_t a, b, ra, rb;
1214
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 a = MBEDTLS_GET_UINT64_LE(x, 0);
1216 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001217
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1219 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001220
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1222 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001223}
1224
Aorimn5f778012016-06-09 23:22:58 +02001225/*
1226 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001227 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001228 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001229 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001230 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001231#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001232MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001233#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001234int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1235 int mode,
1236 size_t length,
1237 const unsigned char data_unit[16],
1238 const unsigned char *input,
1239 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001240{
Janos Follath24eed8d2019-11-22 13:21:35 +00001241 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001242 size_t blocks = length / 16;
1243 size_t leftover = length % 16;
1244 unsigned char tweak[16];
1245 unsigned char prev_tweak[16];
1246 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001247
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001249 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001251
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001252 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001254 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 }
Aorimn5f778012016-06-09 23:22:58 +02001256
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001257 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001259 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 }
Aorimn5f778012016-06-09 23:22:58 +02001261
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1264 data_unit, tweak);
1265 if (ret != 0) {
1266 return ret;
1267 }
Aorimn5f778012016-06-09 23:22:58 +02001268
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001270 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001271 /* We are on the last block in a decrypt operation that has
1272 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001273 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 * the leftovers and then update the current tweak for use on this,
1275 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001276 memcpy(prev_tweak, tweak, sizeof(tweak));
1277 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001278 }
1279
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1283 if (ret != 0) {
1284 return ret;
1285 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001286
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001288
1289 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001291
1292 output += 16;
1293 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001294 }
1295
Gilles Peskine449bd832023-01-11 14:50:10 +01001296 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001297 /* If we are on the leftover bytes in a decrypt operation, we need to
1298 * use the previous tweak for these bytes (as saved in prev_tweak). */
1299 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001300
Jaeden Amerod82cd862018-04-28 15:02:45 +01001301 /* We are now on the final part of the data unit, which doesn't divide
1302 * evenly by 16. It's time for ciphertext stealing. */
1303 size_t i;
1304 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001305
Jaeden Amerod82cd862018-04-28 15:02:45 +01001306 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001307 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001309 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001310 }
Aorimn5f778012016-06-09 23:22:58 +02001311
Dave Rodgman069e7f42022-11-24 19:37:26 +00001312 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001314
Jaeden Amerod82cd862018-04-28 15:02:45 +01001315 /* Copy ciphertext bytes from the previous block for input in this
1316 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001318
Gilles Peskine449bd832023-01-11 14:50:10 +01001319 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1320 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001321 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 }
Aorimn5f778012016-06-09 23:22:58 +02001323
Jaeden Amerod82cd862018-04-28 15:02:45 +01001324 /* Write the result back to the previous block, overriding the previous
1325 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001327 }
1328
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001330}
1331#endif /* MBEDTLS_CIPHER_MODE_XTS */
1332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001333#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001334/*
1335 * AES-CFB128 buffer encryption/decryption
1336 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001337int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1338 int mode,
1339 size_t length,
1340 size_t *iv_off,
1341 unsigned char iv[16],
1342 const unsigned char *input,
1343 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001344{
Paul Bakker27fdf462011-06-09 13:55:13 +00001345 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001346 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001347 size_t n;
1348
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001350 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001351 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001352
1353 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001354
Gilles Peskine449bd832023-01-11 14:50:10 +01001355 if (n > 15) {
1356 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1357 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001358
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 if (mode == MBEDTLS_AES_DECRYPT) {
1360 while (length--) {
1361 if (n == 0) {
1362 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1363 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001364 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001366 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001367
1368 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001370 iv[n] = (unsigned char) c;
1371
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001373 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 } else {
1375 while (length--) {
1376 if (n == 0) {
1377 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1378 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001379 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001381 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001382
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001384
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001386 }
1387 }
1388
1389 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001390 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001391
Gilles Peskine7820a572021-07-07 21:08:28 +02001392exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001394}
Paul Bakker556efba2014-01-24 15:38:12 +01001395
1396/*
1397 * AES-CFB8 buffer encryption/decryption
1398 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001399int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1400 int mode,
1401 size_t length,
1402 unsigned char iv[16],
1403 const unsigned char *input,
1404 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001405{
Gilles Peskine7820a572021-07-07 21:08:28 +02001406 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001407 unsigned char c;
1408 unsigned char ov[17];
1409
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001411 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001412 }
1413 while (length--) {
1414 memcpy(ov, iv, 16);
1415 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1416 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001417 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 }
Paul Bakker556efba2014-01-24 15:38:12 +01001419
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001421 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 }
Paul Bakker556efba2014-01-24 15:38:12 +01001423
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001425
Gilles Peskine449bd832023-01-11 14:50:10 +01001426 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001427 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001428 }
Paul Bakker556efba2014-01-24 15:38:12 +01001429
Gilles Peskine449bd832023-01-11 14:50:10 +01001430 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001431 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001432 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001433
Gilles Peskine7820a572021-07-07 21:08:28 +02001434exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001435 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001436}
Simon Butcher76a5b222018-04-22 22:57:27 +01001437#endif /* MBEDTLS_CIPHER_MODE_CFB */
1438
1439#if defined(MBEDTLS_CIPHER_MODE_OFB)
1440/*
1441 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1442 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001443int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1444 size_t length,
1445 size_t *iv_off,
1446 unsigned char iv[16],
1447 const unsigned char *input,
1448 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001449{
Simon Butcherad4e4932018-04-29 00:43:47 +01001450 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001451 size_t n;
1452
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001453 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001454
Gilles Peskine449bd832023-01-11 14:50:10 +01001455 if (n > 15) {
1456 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1457 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001458
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 while (length--) {
1460 if (n == 0) {
1461 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1462 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001463 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001464 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001465 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001466 *output++ = *input++ ^ iv[n];
1467
Gilles Peskine449bd832023-01-11 14:50:10 +01001468 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001469 }
1470
1471 *iv_off = n;
1472
Simon Butcherad4e4932018-04-29 00:43:47 +01001473exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001474 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001475}
1476#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001478#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001479/*
1480 * AES-CTR buffer encryption/decryption
1481 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001482int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1483 size_t length,
1484 size_t *nc_off,
1485 unsigned char nonce_counter[16],
1486 unsigned char stream_block[16],
1487 const unsigned char *input,
1488 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489{
Paul Bakker369e14b2012-04-18 14:16:09 +00001490 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001491 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001492 size_t n;
1493
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001494 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001495
Gilles Peskine449bd832023-01-11 14:50:10 +01001496 if (n > 0x0F) {
1497 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1498 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001499
Gilles Peskine449bd832023-01-11 14:50:10 +01001500 while (length--) {
1501 if (n == 0) {
1502 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1503 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001504 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001505 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001506
Gilles Peskine449bd832023-01-11 14:50:10 +01001507 for (i = 16; i > 0; i--) {
1508 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001509 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001510 }
1511 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001512 }
1513 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001514 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001515
Gilles Peskine449bd832023-01-11 14:50:10 +01001516 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001517 }
1518
1519 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001520 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001521
Gilles Peskine7820a572021-07-07 21:08:28 +02001522exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001523 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001524}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001527#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001528
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001529#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001530/*
1531 * AES test vectors from:
1532 *
1533 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1534 */
Yanray Wang62c99912023-05-11 11:06:53 +08001535static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001536{
1537 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1538 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001539#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001540 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1541 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1542 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1543 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001544#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001545};
1546
Yanray Wang62c99912023-05-11 11:06:53 +08001547static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001548{
1549 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1550 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001551#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001552 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1553 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1554 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1555 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001556#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001557};
1558
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001559#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001560static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001561{
1562 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1563 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001564#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001565 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1566 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1567 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1568 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001569#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001570};
1571
Yanray Wang62c99912023-05-11 11:06:53 +08001572static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001573{
1574 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1575 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001576#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001577 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1578 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1579 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1580 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001581#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001582};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001583#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001584
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001585#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001586/*
1587 * AES-CFB128 test vectors from:
1588 *
1589 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1590 */
Yanray Wang62c99912023-05-11 11:06:53 +08001591static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001592{
1593 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1594 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001595#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001596 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1597 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1598 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1599 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1600 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1601 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1602 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001603#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001604};
1605
1606static const unsigned char aes_test_cfb128_iv[16] =
1607{
1608 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1609 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1610};
1611
1612static const unsigned char aes_test_cfb128_pt[64] =
1613{
1614 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1615 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1616 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1617 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1618 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1619 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1620 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1621 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1622};
1623
Yanray Wang62c99912023-05-11 11:06:53 +08001624static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001625{
1626 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1627 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1628 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1629 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1630 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1631 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1632 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1633 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001634#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001635 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1636 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1637 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1638 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1639 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1640 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1641 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1642 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1643 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1644 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1645 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1646 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1647 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1648 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1649 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1650 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001651#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001652};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001653#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001654
Simon Butcherad4e4932018-04-29 00:43:47 +01001655#if defined(MBEDTLS_CIPHER_MODE_OFB)
1656/*
1657 * AES-OFB test vectors from:
1658 *
Simon Butcher5db13622018-06-04 22:11:25 +01001659 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001660 */
Yanray Wang62c99912023-05-11 11:06:53 +08001661static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001662{
1663 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1664 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001665#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001666 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1667 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1668 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1669 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1670 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1671 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1672 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001673#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001674};
1675
1676static const unsigned char aes_test_ofb_iv[16] =
1677{
1678 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1679 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1680};
1681
1682static const unsigned char aes_test_ofb_pt[64] =
1683{
1684 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1685 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1686 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1687 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1688 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1689 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1690 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1691 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1692};
1693
Yanray Wang62c99912023-05-11 11:06:53 +08001694static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001695{
1696 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1697 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1698 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1699 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1700 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1701 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1702 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1703 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001704#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001705 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1706 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1707 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1708 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1709 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1710 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1711 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1712 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1713 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1714 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1715 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1716 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1717 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1718 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1719 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1720 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001721#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001722};
1723#endif /* MBEDTLS_CIPHER_MODE_OFB */
1724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001725#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001726/*
1727 * AES-CTR test vectors from:
1728 *
1729 * http://www.faqs.org/rfcs/rfc3686.html
1730 */
1731
Yanray Wang62c99912023-05-11 11:06:53 +08001732static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001733{
1734 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1735 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1736 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1737 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1738 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1739 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1740};
1741
Yanray Wang62c99912023-05-11 11:06:53 +08001742static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001743{
1744 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1745 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1746 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1747 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1748 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1749 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1750};
1751
Yanray Wang62c99912023-05-11 11:06:53 +08001752static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001753{
1754 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1755 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001756 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1757 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1758 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1759 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1760
1761 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1762 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1763 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1764 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1765 0x20, 0x21, 0x22, 0x23 }
1766};
1767
Yanray Wang62c99912023-05-11 11:06:53 +08001768static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001769{
1770 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1771 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1772 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1773 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1774 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1775 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1776 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1777 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1778 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1779 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1780 0x25, 0xB2, 0x07, 0x2F }
1781};
1782
1783static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001784{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001785#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001786
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001787#if defined(MBEDTLS_CIPHER_MODE_XTS)
1788/*
1789 * AES-XTS test vectors from:
1790 *
1791 * IEEE P1619/D16 Annex B
1792 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1793 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1794 */
1795static const unsigned char aes_test_xts_key[][32] =
1796{
1797 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1800 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1801 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1802 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1803 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1804 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1805 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1806 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1807 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1808 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1809};
1810
1811static const unsigned char aes_test_xts_pt32[][32] =
1812{
1813 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1823 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1824 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1825};
1826
1827static const unsigned char aes_test_xts_ct32[][32] =
1828{
1829 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1830 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1831 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1832 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1833 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1834 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1835 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1836 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1837 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1838 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1839 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1840 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1841};
1842
1843static const unsigned char aes_test_xts_data_unit[][16] =
1844{
Gilles Peskine449bd832023-01-11 14:50:10 +01001845 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1847 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1849 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001851};
1852
1853#endif /* MBEDTLS_CIPHER_MODE_XTS */
1854
Paul Bakker5121ce52009-01-03 21:22:43 +00001855/*
1856 * Checkup routine
1857 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001858int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001859{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001860 int ret = 0, i, j, u, mode;
1861 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001862 unsigned char key[32];
1863 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001864 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001865#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1866 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001867 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001868#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001869#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001870 unsigned char prv[16];
1871#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001872#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1873 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001874 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001875#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001876#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001877 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001878#endif
1879#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001880 unsigned char nonce_counter[16];
1881 unsigned char stream_block[16];
1882#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001883 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001884
Gilles Peskine449bd832023-01-11 14:50:10 +01001885 memset(key, 0, 32);
1886 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001887
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001888 if (verbose != 0) {
1889#if defined(MBEDTLS_AES_ALT)
1890 mbedtls_printf(" AES note: alternative implementation.\n");
1891#else /* MBEDTLS_AES_ALT */
1892#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1893 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1894 mbedtls_printf(" AES note: using VIA Padlock.\n");
1895 } else
1896#endif
1897#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001898#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001899 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001900#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001901 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001902#else
1903#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1904#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001905 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1906 mbedtls_printf(" AES note: using AESNI.\n");
1907 } else
1908#endif
1909#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1910 if (mbedtls_aesce_has_support()) {
1911 mbedtls_printf(" AES note: using AESCE.\n");
1912 } else
1913#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001914 {
1915#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1916 mbedtls_printf(" AES note: built-in implementation.\n");
1917#endif
1918 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001919#endif /* MBEDTLS_AES_ALT */
1920 }
1921
Paul Bakker5121ce52009-01-03 21:22:43 +00001922 /*
1923 * ECB mode
1924 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001925 {
1926 static const int num_tests =
1927 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001928
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001929 for (i = 0; i < num_tests << 1; i++) {
1930 u = i >> 1;
1931 keybits = 128 + u * 64;
1932 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001933
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001934 if (verbose != 0) {
1935 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1936 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1937 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001938
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001939 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001940
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001941 if (mode == MBEDTLS_AES_DECRYPT) {
1942 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1943 aes_tests = aes_test_ecb_dec[u];
1944 } else {
1945 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1946 aes_tests = aes_test_ecb_enc[u];
1947 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001948
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001949 /*
1950 * AES-192 is an optional feature that may be unavailable when
1951 * there is an alternative underlying implementation i.e. when
1952 * MBEDTLS_AES_ALT is defined.
1953 */
1954 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1955 mbedtls_printf("skipped\n");
1956 continue;
1957 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001958 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001959 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001960
1961 for (j = 0; j < 10000; j++) {
1962 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1963 if (ret != 0) {
1964 goto exit;
1965 }
1966 }
1967
1968 if (memcmp(buf, aes_tests, 16) != 0) {
1969 ret = 1;
1970 goto exit;
1971 }
1972
1973 if (verbose != 0) {
1974 mbedtls_printf("passed\n");
1975 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001976 }
1977
Gilles Peskine449bd832023-01-11 14:50:10 +01001978 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001979 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001980 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001981 }
1982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001983#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001984 /*
1985 * CBC mode
1986 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001987 {
1988 static const int num_tests =
1989 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001990
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001991 for (i = 0; i < num_tests << 1; i++) {
1992 u = i >> 1;
1993 keybits = 128 + u * 64;
1994 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001995
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001996 if (verbose != 0) {
1997 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1998 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001999 }
2000
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002001 memset(iv, 0, 16);
2002 memset(prv, 0, 16);
2003 memset(buf, 0, 16);
2004
2005 if (mode == MBEDTLS_AES_DECRYPT) {
2006 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2007 aes_tests = aes_test_cbc_dec[u];
2008 } else {
2009 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2010 aes_tests = aes_test_cbc_enc[u];
2011 }
2012
2013 /*
2014 * AES-192 is an optional feature that may be unavailable when
2015 * there is an alternative underlying implementation i.e. when
2016 * MBEDTLS_AES_ALT is defined.
2017 */
2018 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2019 mbedtls_printf("skipped\n");
2020 continue;
2021 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002022 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002023 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002024
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002025 for (j = 0; j < 10000; j++) {
2026 if (mode == MBEDTLS_AES_ENCRYPT) {
2027 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002028
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002029 memcpy(tmp, prv, 16);
2030 memcpy(prv, buf, 16);
2031 memcpy(buf, tmp, 16);
2032 }
2033
2034 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2035 if (ret != 0) {
2036 goto exit;
2037 }
2038
2039 }
2040
2041 if (memcmp(buf, aes_tests, 16) != 0) {
2042 ret = 1;
2043 goto exit;
2044 }
2045
2046 if (verbose != 0) {
2047 mbedtls_printf("passed\n");
2048 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002049 }
2050
Gilles Peskine449bd832023-01-11 14:50:10 +01002051 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002052 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002053 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002054 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002055#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002057#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002058 /*
2059 * CFB128 mode
2060 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002061 {
2062 static const int num_tests =
2063 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002064
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002065 for (i = 0; i < num_tests << 1; i++) {
2066 u = i >> 1;
2067 keybits = 128 + u * 64;
2068 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002069
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002070 if (verbose != 0) {
2071 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2072 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2073 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002074
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002075 memcpy(iv, aes_test_cfb128_iv, 16);
2076 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002077
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002078 offset = 0;
2079 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2080 /*
2081 * AES-192 is an optional feature that may be unavailable when
2082 * there is an alternative underlying implementation i.e. when
2083 * MBEDTLS_AES_ALT is defined.
2084 */
2085 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2086 mbedtls_printf("skipped\n");
2087 continue;
2088 } else if (ret != 0) {
2089 goto exit;
2090 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002091
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002092 if (mode == MBEDTLS_AES_DECRYPT) {
2093 memcpy(buf, aes_test_cfb128_ct[u], 64);
2094 aes_tests = aes_test_cfb128_pt;
2095 } else {
2096 memcpy(buf, aes_test_cfb128_pt, 64);
2097 aes_tests = aes_test_cfb128_ct[u];
2098 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002099
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002100 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2101 if (ret != 0) {
2102 goto exit;
2103 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002104
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002105 if (memcmp(buf, aes_tests, 64) != 0) {
2106 ret = 1;
2107 goto exit;
2108 }
2109
2110 if (verbose != 0) {
2111 mbedtls_printf("passed\n");
2112 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002113 }
2114
Gilles Peskine449bd832023-01-11 14:50:10 +01002115 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002116 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002117 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002119#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002120
Simon Butcherad4e4932018-04-29 00:43:47 +01002121#if defined(MBEDTLS_CIPHER_MODE_OFB)
2122 /*
2123 * OFB mode
2124 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002125 {
2126 static const int num_tests =
2127 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002128
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002129 for (i = 0; i < num_tests << 1; i++) {
2130 u = i >> 1;
2131 keybits = 128 + u * 64;
2132 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002133
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002134 if (verbose != 0) {
2135 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2136 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2137 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002138
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002139 memcpy(iv, aes_test_ofb_iv, 16);
2140 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002141
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002142 offset = 0;
2143 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2144 /*
2145 * AES-192 is an optional feature that may be unavailable when
2146 * there is an alternative underlying implementation i.e. when
2147 * MBEDTLS_AES_ALT is defined.
2148 */
2149 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2150 mbedtls_printf("skipped\n");
2151 continue;
2152 } else if (ret != 0) {
2153 goto exit;
2154 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002155
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002156 if (mode == MBEDTLS_AES_DECRYPT) {
2157 memcpy(buf, aes_test_ofb_ct[u], 64);
2158 aes_tests = aes_test_ofb_pt;
2159 } else {
2160 memcpy(buf, aes_test_ofb_pt, 64);
2161 aes_tests = aes_test_ofb_ct[u];
2162 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002163
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002164 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2165 if (ret != 0) {
2166 goto exit;
2167 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002168
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002169 if (memcmp(buf, aes_tests, 64) != 0) {
2170 ret = 1;
2171 goto exit;
2172 }
2173
2174 if (verbose != 0) {
2175 mbedtls_printf("passed\n");
2176 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002177 }
2178
Gilles Peskine449bd832023-01-11 14:50:10 +01002179 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002180 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002181 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002182 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002183#endif /* MBEDTLS_CIPHER_MODE_OFB */
2184
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002185#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002186 /*
2187 * CTR mode
2188 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002189 {
2190 static const int num_tests =
2191 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002192
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002193 for (i = 0; i < num_tests << 1; i++) {
2194 u = i >> 1;
2195 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002196
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002197 if (verbose != 0) {
2198 mbedtls_printf(" AES-CTR-128 (%s): ",
2199 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2200 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002201
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002202 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2203 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002204
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002205 offset = 0;
2206 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2207 goto exit;
2208 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002209
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002210 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002211
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002212 if (mode == MBEDTLS_AES_DECRYPT) {
2213 memcpy(buf, aes_test_ctr_ct[u], len);
2214 aes_tests = aes_test_ctr_pt[u];
2215 } else {
2216 memcpy(buf, aes_test_ctr_pt[u], len);
2217 aes_tests = aes_test_ctr_ct[u];
2218 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002219
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002220 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2221 stream_block, buf, buf);
2222 if (ret != 0) {
2223 goto exit;
2224 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002225
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002226 if (memcmp(buf, aes_tests, len) != 0) {
2227 ret = 1;
2228 goto exit;
2229 }
2230
2231 if (verbose != 0) {
2232 mbedtls_printf("passed\n");
2233 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002234 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002235 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002236
Gilles Peskine449bd832023-01-11 14:50:10 +01002237 if (verbose != 0) {
2238 mbedtls_printf("\n");
2239 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002240#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002241
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002242#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002243 /*
2244 * XTS mode
2245 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 static const int num_tests =
2248 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2249 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002250
Gilles Peskine449bd832023-01-11 14:50:10 +01002251 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002252
Gilles Peskine449bd832023-01-11 14:50:10 +01002253 for (i = 0; i < num_tests << 1; i++) {
2254 const unsigned char *data_unit;
2255 u = i >> 1;
2256 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002257
Gilles Peskine449bd832023-01-11 14:50:10 +01002258 if (verbose != 0) {
2259 mbedtls_printf(" AES-XTS-128 (%s): ",
2260 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2261 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002262
Gilles Peskine449bd832023-01-11 14:50:10 +01002263 memset(key, 0, sizeof(key));
2264 memcpy(key, aes_test_xts_key[u], 32);
2265 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002266
Gilles Peskine449bd832023-01-11 14:50:10 +01002267 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002268
Gilles Peskine449bd832023-01-11 14:50:10 +01002269 if (mode == MBEDTLS_AES_DECRYPT) {
2270 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2271 if (ret != 0) {
2272 goto exit;
2273 }
2274 memcpy(buf, aes_test_xts_ct32[u], len);
2275 aes_tests = aes_test_xts_pt32[u];
2276 } else {
2277 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2278 if (ret != 0) {
2279 goto exit;
2280 }
2281 memcpy(buf, aes_test_xts_pt32[u], len);
2282 aes_tests = aes_test_xts_ct32[u];
2283 }
2284
2285
2286 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2287 buf, buf);
2288 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002289 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002290 }
2291
2292 if (memcmp(buf, aes_tests, len) != 0) {
2293 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002294 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002295 }
2296
2297 if (verbose != 0) {
2298 mbedtls_printf("passed\n");
2299 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002300 }
2301
Gilles Peskine449bd832023-01-11 14:50:10 +01002302 if (verbose != 0) {
2303 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002304 }
2305
Gilles Peskine449bd832023-01-11 14:50:10 +01002306 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002307 }
2308#endif /* MBEDTLS_CIPHER_MODE_XTS */
2309
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002310 ret = 0;
2311
2312exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002313 if (ret != 0 && verbose != 0) {
2314 mbedtls_printf("failed\n");
2315 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002316
Gilles Peskine449bd832023-01-11 14:50:10 +01002317 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002318
Gilles Peskine449bd832023-01-11 14:50:10 +01002319 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002320}
2321
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002322#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002324#endif /* MBEDTLS_AES_C */