blob: dd803fe4c8774ead708ceac96f838358a88de70d [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010022 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000023 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Dave Rodgman782df0352023-09-29 12:57:52 +010037#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
38#if !((defined(MBEDTLS_ARCH_IS_ARM64) && defined(MBEDTLS_AESCE_C)) || \
39 (defined(MBEDTLS_ARCH_IS_X64) && defined(MBEDTLS_AESNI_C)) || \
40 (defined(MBEDTLS_ARCH_IS_X86) && defined(MBEDTLS_AESNI_C)))
Jerry Yu69436812023-04-25 11:08:30 +080041#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080042#endif
43#endif
44
Jerry Yu61fc5ed2023-08-18 17:28:48 +080045#if defined(MBEDTLS_PADLOCK_C)
46#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080047#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
48#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080049#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
50#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
51 "MBEDTLS_PADLOCK_C is set"
52#endif
53#endif
Jerry Yu02b15192023-04-23 14:43:19 +080054#endif
55
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000057#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000058#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000060#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010061#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080062#if defined(MBEDTLS_AESCE_C)
63#include "aesce.h"
64#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000065
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000066#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020069
Jerry Yu9e628622023-08-17 11:20:09 +080070#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000071static int aes_padlock_ace = -1;
72#endif
73
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000075/*
76 * Forward S-box
77 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010078#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
79 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000080static const unsigned char FSb[256] =
81{
82 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
83 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
84 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
85 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
86 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
87 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
88 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
89 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
90 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
91 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
92 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
93 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
94 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
95 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
96 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
97 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
98 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
99 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
100 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
101 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
102 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
103 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
104 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
105 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
106 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
107 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
108 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
109 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
110 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
111 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
112 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
113 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
114};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100115#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
116 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000117
118/*
119 * Forward tables
120 */
121#define FT \
122\
Gilles Peskine449bd832023-01-11 14:50:10 +0100123 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
124 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
125 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
126 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
127 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
128 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
129 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
130 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
131 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
132 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
133 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
134 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
135 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
136 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
137 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
138 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
139 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
140 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
141 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
142 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
143 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
144 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
145 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
146 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
147 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
148 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
149 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
150 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
151 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
152 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
153 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
154 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
155 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
156 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
157 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
158 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
159 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
160 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
161 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
162 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
163 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
164 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
165 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
166 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
167 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
168 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
169 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
170 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
171 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
172 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
173 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
174 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
175 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
176 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
177 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
178 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
179 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
180 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
181 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
182 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
183 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
184 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
185 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
186 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 +0000187
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100188#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100189#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000190static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000191#undef V
192
Hanno Beckerad049a92017-06-19 16:31:54 +0100193#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000196static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000197#undef V
198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000201#undef V
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000204static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000205#undef V
206
Hanno Becker177d3cf2017-06-07 15:52:48 +0100207#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200208
Dave Rodgman1be24632023-06-29 12:01:24 +0100209#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
210
Paul Bakker5121ce52009-01-03 21:22:43 +0000211#undef FT
212
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100213#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000214/*
215 * Reverse S-box
216 */
217static const unsigned char RSb[256] =
218{
219 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
220 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
221 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
222 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
223 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
224 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
225 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
226 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
227 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
228 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
229 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
230 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
231 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
232 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
233 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
234 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
235 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
236 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
237 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
238 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
239 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
240 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
241 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
242 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
243 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
244 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
245 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
246 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
247 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
248 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
249 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
250 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
251};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100252#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
254/*
255 * Reverse tables
256 */
257#define RT \
258\
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
260 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
261 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
262 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
263 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
264 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
265 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
266 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
267 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
268 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
269 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
270 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
271 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
272 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
273 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
274 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
275 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
276 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
277 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
278 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
279 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
280 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
281 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
282 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
283 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
284 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
285 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
286 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
287 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
288 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
289 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
290 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
291 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
292 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
293 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
294 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
295 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
296 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
297 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
298 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
299 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
300 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
301 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
302 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
303 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
304 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
305 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
306 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
307 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
308 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
309 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
310 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
311 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
312 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
313 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
314 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
315 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
316 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
317 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
318 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
319 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
320 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
321 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
322 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 +0000323
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100324#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000327static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000328#undef V
329
Hanno Beckerad049a92017-06-19 16:31:54 +0100330#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000333static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000334#undef V
335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000338#undef V
339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000341static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000342#undef V
343
Hanno Becker177d3cf2017-06-07 15:52:48 +0100344#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200345
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800346#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
347
Paul Bakker5121ce52009-01-03 21:22:43 +0000348#undef RT
349
Dave Rodgman34152a42023-06-27 18:31:24 +0100350#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000351/*
352 * Round constants
353 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000354static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000355{
356 0x00000001, 0x00000002, 0x00000004, 0x00000008,
357 0x00000010, 0x00000020, 0x00000040, 0x00000080,
358 0x0000001B, 0x00000036
359};
Dave Rodgman34152a42023-06-27 18:31:24 +0100360#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
364/*
365 * Forward S-box & tables
366 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100367#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
368 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000369static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100370#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
371 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100372#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200373static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100374#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200375static uint32_t FT1[256];
376static uint32_t FT2[256];
377static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100378#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100379#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000380
381/*
382 * Reverse S-box & tables
383 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100384#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000385static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100386#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100387
388#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000389static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100390#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000391static uint32_t RT1[256];
392static uint32_t RT2[256];
393static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100394#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100395#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
Dave Rodgman8c753f92023-06-27 18:16:13 +0100397#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000398/*
399 * Round constants
400 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000401static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
403/*
404 * Tables generation code
405 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100406#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
407#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
408#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410static int aes_init_done = 0;
411
Gilles Peskine449bd832023-01-11 14:50:10 +0100412static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000413{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800414 int i;
415 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800416 uint8_t pow[256];
417 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
419 /*
420 * compute pow and log tables over GF(2^8)
421 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800424 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800425 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 }
427
428 /*
429 * calculate the round constants
430 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800432 RCON[i] = x;
433 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 }
435
436 /*
437 * generate the forward and reverse S-boxes
438 */
439 FSb[0x00] = 0x63;
440 RSb[0x63] = 0x00;
441
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000443 x = pow[255 - log[i]];
444
Yanray Wangfe944ce2023-06-26 18:16:01 +0800445 y = x; y = (y << 1) | (y >> 7);
446 x ^= y; y = (y << 1) | (y >> 7);
447 x ^= y; y = (y << 1) | (y >> 7);
448 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 x ^= y ^ 0x63;
450
Yanray Wangfe944ce2023-06-26 18:16:01 +0800451 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 RSb[x] = (unsigned char) i;
453 }
454
455 /*
456 * generate the forward and reverse tables
457 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100458 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000459 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800460 y = XTIME(x);
461 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 FT0[i] = ((uint32_t) y) ^
464 ((uint32_t) x << 8) ^
465 ((uint32_t) x << 16) ^
466 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
Hanno Beckerad049a92017-06-19 16:31:54 +0100468#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 FT1[i] = ROTL8(FT0[i]);
470 FT2[i] = ROTL8(FT1[i]);
471 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100472#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
474 x = RSb[i];
475
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100476#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
478 ((uint32_t) MUL(0x09, x) << 8) ^
479 ((uint32_t) MUL(0x0D, x) << 16) ^
480 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000481
Hanno Beckerad049a92017-06-19 16:31:54 +0100482#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 RT1[i] = ROTL8(RT0[i]);
484 RT2[i] = ROTL8(RT1[i]);
485 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100486#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100487#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000488 }
489}
490
Dave Rodgman8c753f92023-06-27 18:16:13 +0100491#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
492
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200493#undef ROTL8
494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000496
Hanno Beckerad049a92017-06-19 16:31:54 +0100497#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
500#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
501#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200502
503#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100504#define AES_RT1(idx) ROTL8(RT0[idx])
505#define AES_RT2(idx) ROTL16(RT0[idx])
506#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200507
508#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100509#define AES_FT1(idx) ROTL8(FT0[idx])
510#define AES_FT2(idx) ROTL16(FT0[idx])
511#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200512
Hanno Becker177d3cf2017-06-07 15:52:48 +0100513#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200514
515#define AES_RT0(idx) RT0[idx]
516#define AES_RT1(idx) RT1[idx]
517#define AES_RT2(idx) RT2[idx]
518#define AES_RT3(idx) RT3[idx]
519
520#define AES_FT0(idx) FT0[idx]
521#define AES_FT1(idx) FT1[idx]
522#define AES_FT2(idx) FT2[idx]
523#define AES_FT3(idx) FT3[idx]
524
Hanno Becker177d3cf2017-06-07 15:52:48 +0100525#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200526
Gilles Peskine449bd832023-01-11 14:50:10 +0100527void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200528{
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200530}
531
Gilles Peskine449bd832023-01-11 14:50:10 +0100532void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200533{
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200535 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200537
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200539}
540
Jaeden Amero9366feb2018-05-29 18:55:17 +0100541#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100542void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100543{
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 mbedtls_aes_init(&ctx->crypt);
545 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100546}
547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100549{
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100551 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 }
Simon Butcher5201e412018-12-06 17:40:14 +0000553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 mbedtls_aes_free(&ctx->crypt);
555 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100556}
557#endif /* MBEDTLS_CIPHER_MODE_XTS */
558
Gilles Peskine0de8f852023-03-16 17:14:59 +0100559/* Some implementations need the round keys to be aligned.
560 * Return an offset to be added to buf, such that (buf + offset) is
561 * correctly aligned.
562 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
563 * i.e. an offset of 1 means 4 bytes and so on.
564 */
Jerry Yu96084472023-08-17 18:10:45 +0800565#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100566 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100567#define MAY_NEED_TO_ALIGN
568#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100569
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100570#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
571 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100572static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
573{
574#if defined(MAY_NEED_TO_ALIGN)
575 int align_16_bytes = 0;
576
Jerry Yu9e628622023-08-17 11:20:09 +0800577#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100578 if (aes_padlock_ace == -1) {
579 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
580 }
581 if (aes_padlock_ace) {
582 align_16_bytes = 1;
583 }
584#endif
585
Gilles Peskine9c682e72023-03-16 17:21:33 +0100586#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100587 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
588 align_16_bytes = 1;
589 }
590#endif
591
592 if (align_16_bytes) {
593 /* These implementations needs 16-byte alignment
594 * for the round key array. */
595 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
596 if (delta == 0) {
597 return 0;
598 } else {
599 return 4 - delta; // 16 bytes = 4 uint32_t
600 }
601 }
602#else /* MAY_NEED_TO_ALIGN */
603 (void) buf;
604#endif /* MAY_NEED_TO_ALIGN */
605
606 return 0;
607}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100608#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
609 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100610
Paul Bakker5121ce52009-01-03 21:22:43 +0000611/*
612 * AES key schedule (encryption)
613 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200614#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100615int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
616 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000617{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000618 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000621 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800622#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000623 case 192: ctx->nr = 12; break;
624 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800625#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 }
628
Simon Butcher5201e412018-12-06 17:40:14 +0000629#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000631 aes_gen_tables();
632 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000633 }
634#endif
635
Gilles Peskine0de8f852023-03-16 17:14:59 +0100636 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100637 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100639#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
641 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
642 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100643#endif
644
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800645#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100646 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800647 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
648 }
649#endif
650
Jerry Yu29c91ba2023-08-04 11:02:04 +0800651#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800652 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 }
655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 case 10:
658
Jerry Yu3a0f0442023-08-17 17:06:21 +0800659 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100661 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
662 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
663 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
664 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
666 RK[5] = RK[1] ^ RK[4];
667 RK[6] = RK[2] ^ RK[5];
668 RK[7] = RK[3] ^ RK[6];
669 }
670 break;
671
Arto Kinnunen732ca322023-04-14 14:26:10 +0800672#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 case 12:
674
Jerry Yu3a0f0442023-08-17 17:06:21 +0800675 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000676 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
678 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
679 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
680 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
682 RK[7] = RK[1] ^ RK[6];
683 RK[8] = RK[2] ^ RK[7];
684 RK[9] = RK[3] ^ RK[8];
685 RK[10] = RK[4] ^ RK[9];
686 RK[11] = RK[5] ^ RK[10];
687 }
688 break;
689
690 case 14:
691
Jerry Yu3a0f0442023-08-17 17:06:21 +0800692 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000693 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
695 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
696 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
697 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
699 RK[9] = RK[1] ^ RK[8];
700 RK[10] = RK[2] ^ RK[9];
701 RK[11] = RK[3] ^ RK[10];
702
703 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
705 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
706 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
707 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
709 RK[13] = RK[5] ^ RK[12];
710 RK[14] = RK[6] ^ RK[13];
711 RK[15] = RK[7] ^ RK[14];
712 }
713 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800714#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000715 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000716
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800718#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000719}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200720#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000721
722/*
723 * AES key schedule (decryption)
724 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200725#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100726int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
727 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000728{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800729#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800730 uint32_t *SK;
731#endif
732 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200733 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000734 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800735
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200736
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000738
Gilles Peskine0de8f852023-03-16 17:14:59 +0100739 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100740 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000741
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200742 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200744 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000746
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200747 ctx->nr = cty.nr;
748
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100749#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
751 mbedtls_aesni_inverse_key((unsigned char *) RK,
752 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200753 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100754 }
755#endif
756
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800757#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100758 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800759 mbedtls_aesce_inverse_key(
760 (unsigned char *) RK,
761 (const unsigned char *) (cty.buf + cty.rk_offset),
762 ctx->nr);
763 goto exit;
764 }
765#endif
766
Jerry Yu29c91ba2023-08-04 11:02:04 +0800767#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100768 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000769
770 *RK++ = *SK++;
771 *RK++ = *SK++;
772 *RK++ = *SK++;
773 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800774 SK -= 8;
775 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
776 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
778 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
779 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
780 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000781 }
782 }
783
784 *RK++ = *SK++;
785 *RK++ = *SK++;
786 *RK++ = *SK++;
787 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800788#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200789exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000793}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100794#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100795
796#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100797static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
798 unsigned int keybits,
799 const unsigned char **key1,
800 unsigned int *key1bits,
801 const unsigned char **key2,
802 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100803{
804 const unsigned int half_keybits = keybits / 2;
805 const unsigned int half_keybytes = half_keybits / 8;
806
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808 case 256: break;
809 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100811 }
812
813 *key1bits = half_keybits;
814 *key2bits = half_keybits;
815 *key1 = &key[0];
816 *key2 = &key[half_keybytes];
817
818 return 0;
819}
820
Gilles Peskine449bd832023-01-11 14:50:10 +0100821int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
822 const unsigned char *key,
823 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100824{
Janos Follath24eed8d2019-11-22 13:21:35 +0000825 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100826 const unsigned char *key1, *key2;
827 unsigned int key1bits, key2bits;
828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
830 &key2, &key2bits);
831 if (ret != 0) {
832 return ret;
833 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100834
835 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
837 if (ret != 0) {
838 return ret;
839 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100840
841 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100842 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100843}
844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
846 const unsigned char *key,
847 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100848{
Janos Follath24eed8d2019-11-22 13:21:35 +0000849 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100850 const unsigned char *key1, *key2;
851 unsigned int key1bits, key2bits;
852
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
854 &key2, &key2bits);
855 if (ret != 0) {
856 return ret;
857 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100858
859 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
861 if (ret != 0) {
862 return ret;
863 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100864
865 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100866 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100867}
868#endif /* MBEDTLS_CIPHER_MODE_XTS */
869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100871 do \
872 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
874 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
875 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
876 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100877 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
879 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
880 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
881 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100882 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
884 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
885 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
886 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100887 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
889 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
890 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
891 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
892 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100895 do \
896 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
898 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
899 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
900 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100901 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
903 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
904 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
905 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100906 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
908 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
909 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
910 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100911 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
913 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
914 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
915 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
916 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
918/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200919 * AES-ECB block encryption
920 */
921#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100922int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
923 const unsigned char input[16],
924 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200925{
926 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100927 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200929 uint32_t X[4];
930 uint32_t Y[4];
931 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200932
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
934 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
935 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
936 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200937
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
939 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]);
940 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 +0200941 }
942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 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 +0200944
Gilles Peskine5197c662020-08-26 17:03:24 +0200945 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
947 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
948 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
949 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200950
Gilles Peskine5197c662020-08-26 17:03:24 +0200951 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
953 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
954 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
955 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200956
Gilles Peskine5197c662020-08-26 17:03:24 +0200957 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
959 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
960 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
961 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Gilles Peskine5197c662020-08-26 17:03:24 +0200963 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
965 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
966 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
967 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
970 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
971 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
972 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200977}
978#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
979
980/*
981 * AES-ECB block decryption
982 */
983#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100984int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
985 const unsigned char input[16],
986 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200987{
988 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100989 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200991 uint32_t X[4];
992 uint32_t Y[4];
993 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200994
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
996 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
997 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
998 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200999
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1001 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]);
1002 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 +02001003 }
1004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 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 +02001006
Gilles Peskine5197c662020-08-26 17:03:24 +02001007 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1009 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1010 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1011 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001012
Gilles Peskine5197c662020-08-26 17:03:24 +02001013 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1015 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1016 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1017 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001018
Gilles Peskine5197c662020-08-26 17:03:24 +02001019 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1021 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1022 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1023 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001024
Gilles Peskine5197c662020-08-26 17:03:24 +02001025 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001026 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1027 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1028 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1029 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001030
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1032 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1033 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1034 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001035
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001039}
1040#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1041
Gilles Peskine0de8f852023-03-16 17:14:59 +01001042#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001043/* VIA Padlock and our intrinsics-based implementation of AESNI require
1044 * the round keys to be aligned on a 16-byte boundary. We take care of this
1045 * before creating them, but the AES context may have moved (this can happen
1046 * if the library is called from a language with managed memory), and in later
1047 * calls it might have a different alignment with respect to 16-byte memory.
1048 * So we may need to realign.
1049 */
1050static void aes_maybe_realign(mbedtls_aes_context *ctx)
1051{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001052 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1053 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001054 memmove(ctx->buf + new_offset, // new address
1055 ctx->buf + ctx->rk_offset, // current address
1056 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1057 ctx->rk_offset = new_offset;
1058 }
1059}
1060#endif
1061
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001062/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 * AES-ECB block encryption/decryption
1064 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001065int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1066 int mode,
1067 const unsigned char input[16],
1068 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001069{
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001071 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001073
Gilles Peskine0de8f852023-03-16 17:14:59 +01001074#if defined(MAY_NEED_TO_ALIGN)
1075 aes_maybe_realign(ctx);
1076#endif
1077
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001078#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1080 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1081 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001082#endif
1083
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001084#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001085 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001086 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1087 }
1088#endif
1089
Jerry Yu9e628622023-08-17 11:20:09 +08001090#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001092 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001093 }
1094#endif
1095
Jerry Yu29c91ba2023-08-04 11:02:04 +08001096#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 if (mode == MBEDTLS_AES_ENCRYPT) {
1098 return mbedtls_internal_aes_encrypt(ctx, input, output);
1099 } else {
1100 return mbedtls_internal_aes_decrypt(ctx, input, output);
1101 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001102#endif
1103
Paul Bakker5121ce52009-01-03 21:22:43 +00001104}
1105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001107
Paul Bakker5121ce52009-01-03 21:22:43 +00001108/*
1109 * AES-CBC buffer encryption/decryption
1110 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001111int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1112 int mode,
1113 size_t length,
1114 unsigned char iv[16],
1115 const unsigned char *input,
1116 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001117{
Gilles Peskine7820a572021-07-07 21:08:28 +02001118 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001119 unsigned char temp[16];
1120
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001122 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001123 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001124
Paul Elliott2ad93672023-08-11 11:07:06 +01001125 /* Nothing to do if length is zero. */
1126 if (length == 0) {
1127 return 0;
1128 }
1129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 if (length % 16) {
1131 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1132 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001133
Jerry Yu9e628622023-08-17 11:20:09 +08001134#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 if (aes_padlock_ace > 0) {
1136 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1137 return 0;
1138 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001139
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001140 // If padlock data misaligned, we just fall back to
1141 // unaccelerated mode
1142 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001143 }
1144#endif
1145
Dave Rodgman906c63c2023-06-14 17:53:51 +01001146 const unsigned char *ivp = iv;
1147
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 if (mode == MBEDTLS_AES_DECRYPT) {
1149 while (length > 0) {
1150 memcpy(temp, input, 16);
1151 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1152 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001153 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001155 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001156 * the result for the next block in CBC, and the cost of transferring that data from
1157 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001158 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001159
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001161
1162 input += 16;
1163 output += 16;
1164 length -= 16;
1165 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 } else {
1167 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001168 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001169
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1171 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001172 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001174 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001175
1176 input += 16;
1177 output += 16;
1178 length -= 16;
1179 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001180 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001181 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001182 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001183
Gilles Peskine7820a572021-07-07 21:08:28 +02001184exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001186}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001187#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001188
Aorimn5f778012016-06-09 23:22:58 +02001189#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001190
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001191typedef unsigned char mbedtls_be128[16];
1192
1193/*
1194 * GF(2^128) multiplication function
1195 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001196 * This function multiplies a field element by x in the polynomial field
1197 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001198 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001199 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001200 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001201#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001202MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001203#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001204static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001205 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001206{
1207 uint64_t a, b, ra, rb;
1208
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 a = MBEDTLS_GET_UINT64_LE(x, 0);
1210 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1213 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001214
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1216 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001217}
1218
Aorimn5f778012016-06-09 23:22:58 +02001219/*
1220 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001221 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001222 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001223 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001224 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001225#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001226MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001227#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001228int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1229 int mode,
1230 size_t length,
1231 const unsigned char data_unit[16],
1232 const unsigned char *input,
1233 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001234{
Janos Follath24eed8d2019-11-22 13:21:35 +00001235 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001236 size_t blocks = length / 16;
1237 size_t leftover = length % 16;
1238 unsigned char tweak[16];
1239 unsigned char prev_tweak[16];
1240 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001241
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001243 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001245
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001246 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001248 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 }
Aorimn5f778012016-06-09 23:22:58 +02001250
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001251 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001253 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 }
Aorimn5f778012016-06-09 23:22:58 +02001255
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1258 data_unit, tweak);
1259 if (ret != 0) {
1260 return ret;
1261 }
Aorimn5f778012016-06-09 23:22:58 +02001262
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001264 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 /* We are on the last block in a decrypt operation that has
1266 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001267 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001268 * the leftovers and then update the current tweak for use on this,
1269 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001270 memcpy(prev_tweak, tweak, sizeof(tweak));
1271 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001272 }
1273
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275
Gilles Peskine449bd832023-01-11 14:50:10 +01001276 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1277 if (ret != 0) {
1278 return ret;
1279 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001280
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282
1283 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285
1286 output += 16;
1287 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001288 }
1289
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001291 /* If we are on the leftover bytes in a decrypt operation, we need to
1292 * use the previous tweak for these bytes (as saved in prev_tweak). */
1293 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001294
Jaeden Amerod82cd862018-04-28 15:02:45 +01001295 /* We are now on the final part of the data unit, which doesn't divide
1296 * evenly by 16. It's time for ciphertext stealing. */
1297 size_t i;
1298 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001299
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001301 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001302 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001303 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001304 }
Aorimn5f778012016-06-09 23:22:58 +02001305
Dave Rodgman069e7f42022-11-24 19:37:26 +00001306 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001308
Jaeden Amerod82cd862018-04-28 15:02:45 +01001309 /* Copy ciphertext bytes from the previous block for input in this
1310 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001312
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1314 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001315 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 }
Aorimn5f778012016-06-09 23:22:58 +02001317
Jaeden Amerod82cd862018-04-28 15:02:45 +01001318 /* Write the result back to the previous block, overriding the previous
1319 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001321 }
1322
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001324}
1325#endif /* MBEDTLS_CIPHER_MODE_XTS */
1326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001327#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001328/*
1329 * AES-CFB128 buffer encryption/decryption
1330 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001331int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1332 int mode,
1333 size_t length,
1334 size_t *iv_off,
1335 unsigned char iv[16],
1336 const unsigned char *input,
1337 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001338{
Paul Bakker27fdf462011-06-09 13:55:13 +00001339 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001340 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001341 size_t n;
1342
Gilles Peskine449bd832023-01-11 14:50:10 +01001343 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001344 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001346
1347 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 if (n > 15) {
1350 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1351 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001352
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 if (mode == MBEDTLS_AES_DECRYPT) {
1354 while (length--) {
1355 if (n == 0) {
1356 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1357 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001358 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001360 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001361
1362 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001364 iv[n] = (unsigned char) c;
1365
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 } else {
1369 while (length--) {
1370 if (n == 0) {
1371 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1372 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001373 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001375 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001376
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001378
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001380 }
1381 }
1382
1383 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001384 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001385
Gilles Peskine7820a572021-07-07 21:08:28 +02001386exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001388}
Paul Bakker556efba2014-01-24 15:38:12 +01001389
1390/*
1391 * AES-CFB8 buffer encryption/decryption
1392 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001393int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1394 int mode,
1395 size_t length,
1396 unsigned char iv[16],
1397 const unsigned char *input,
1398 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001399{
Gilles Peskine7820a572021-07-07 21:08:28 +02001400 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001401 unsigned char c;
1402 unsigned char ov[17];
1403
Gilles Peskine449bd832023-01-11 14:50:10 +01001404 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001405 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001406 }
1407 while (length--) {
1408 memcpy(ov, iv, 16);
1409 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1410 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001411 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001412 }
Paul Bakker556efba2014-01-24 15:38:12 +01001413
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001415 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 }
Paul Bakker556efba2014-01-24 15:38:12 +01001417
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001419
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001421 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 }
Paul Bakker556efba2014-01-24 15:38:12 +01001423
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001425 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001426 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001427
Gilles Peskine7820a572021-07-07 21:08:28 +02001428exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001430}
Simon Butcher76a5b222018-04-22 22:57:27 +01001431#endif /* MBEDTLS_CIPHER_MODE_CFB */
1432
1433#if defined(MBEDTLS_CIPHER_MODE_OFB)
1434/*
1435 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1436 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001437int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1438 size_t length,
1439 size_t *iv_off,
1440 unsigned char iv[16],
1441 const unsigned char *input,
1442 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001443{
Simon Butcherad4e4932018-04-29 00:43:47 +01001444 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001445 size_t n;
1446
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001447 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001448
Gilles Peskine449bd832023-01-11 14:50:10 +01001449 if (n > 15) {
1450 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1451 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001452
Gilles Peskine449bd832023-01-11 14:50:10 +01001453 while (length--) {
1454 if (n == 0) {
1455 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1456 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001457 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001458 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001459 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001460 *output++ = *input++ ^ iv[n];
1461
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001463 }
1464
1465 *iv_off = n;
1466
Simon Butcherad4e4932018-04-29 00:43:47 +01001467exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001468 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001469}
1470#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001473/*
1474 * AES-CTR buffer encryption/decryption
1475 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001476int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1477 size_t length,
1478 size_t *nc_off,
1479 unsigned char nonce_counter[16],
1480 unsigned char stream_block[16],
1481 const unsigned char *input,
1482 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483{
Paul Bakker369e14b2012-04-18 14:16:09 +00001484 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001485 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001486 size_t n;
1487
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001488 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489
Gilles Peskine449bd832023-01-11 14:50:10 +01001490 if (n > 0x0F) {
1491 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1492 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001493
Gilles Peskine449bd832023-01-11 14:50:10 +01001494 while (length--) {
1495 if (n == 0) {
1496 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1497 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001498 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001499 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001500
Gilles Peskine449bd832023-01-11 14:50:10 +01001501 for (i = 16; i > 0; i--) {
1502 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001503 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001504 }
1505 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001506 }
1507 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001508 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001509
Gilles Peskine449bd832023-01-11 14:50:10 +01001510 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001511 }
1512
1513 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001514 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001515
Gilles Peskine7820a572021-07-07 21:08:28 +02001516exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001517 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001518}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001521#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001524/*
1525 * AES test vectors from:
1526 *
1527 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1528 */
Yanray Wang62c99912023-05-11 11:06:53 +08001529static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001530{
1531 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1532 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001533#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001534 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1535 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1536 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1537 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001538#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001539};
1540
Yanray Wang62c99912023-05-11 11:06:53 +08001541static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001542{
1543 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1544 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001545#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001546 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1547 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1548 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1549 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001550#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001551};
1552
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001553#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001554static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001555{
1556 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1557 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001558#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001559 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1560 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1561 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1562 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001563#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001564};
1565
Yanray Wang62c99912023-05-11 11:06:53 +08001566static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001567{
1568 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1569 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001570#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001571 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1572 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1573 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1574 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001575#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001576};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001577#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001578
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001579#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001580/*
1581 * AES-CFB128 test vectors from:
1582 *
1583 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1584 */
Yanray Wang62c99912023-05-11 11:06:53 +08001585static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001586{
1587 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1588 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001589#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001590 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1591 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1592 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1593 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1594 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1595 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1596 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001597#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001598};
1599
1600static const unsigned char aes_test_cfb128_iv[16] =
1601{
1602 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1603 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1604};
1605
1606static const unsigned char aes_test_cfb128_pt[64] =
1607{
1608 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1609 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1610 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1611 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1612 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1613 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1614 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1615 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1616};
1617
Yanray Wang62c99912023-05-11 11:06:53 +08001618static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001619{
1620 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1621 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1622 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1623 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1624 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1625 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1626 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1627 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001628#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001629 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1630 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1631 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1632 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1633 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1634 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1635 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1636 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1637 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1638 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1639 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1640 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1641 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1642 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1643 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1644 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001645#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001646};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001647#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001648
Simon Butcherad4e4932018-04-29 00:43:47 +01001649#if defined(MBEDTLS_CIPHER_MODE_OFB)
1650/*
1651 * AES-OFB test vectors from:
1652 *
Simon Butcher5db13622018-06-04 22:11:25 +01001653 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001654 */
Yanray Wang62c99912023-05-11 11:06:53 +08001655static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001656{
1657 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1658 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001659#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001660 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1661 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1662 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1663 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1664 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1665 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1666 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001667#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001668};
1669
1670static const unsigned char aes_test_ofb_iv[16] =
1671{
1672 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1673 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1674};
1675
1676static const unsigned char aes_test_ofb_pt[64] =
1677{
1678 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1679 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1680 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1681 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1682 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1683 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1684 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1685 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1686};
1687
Yanray Wang62c99912023-05-11 11:06:53 +08001688static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001689{
1690 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1691 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1692 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1693 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1694 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1695 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1696 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1697 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001698#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001699 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1700 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1701 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1702 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1703 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1704 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1705 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1706 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1707 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1708 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1709 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1710 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1711 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1712 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1713 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1714 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001715#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001716};
1717#endif /* MBEDTLS_CIPHER_MODE_OFB */
1718
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001719#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001720/*
1721 * AES-CTR test vectors from:
1722 *
1723 * http://www.faqs.org/rfcs/rfc3686.html
1724 */
1725
Yanray Wang62c99912023-05-11 11:06:53 +08001726static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001727{
1728 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1729 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1730 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1731 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1732 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1733 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1734};
1735
Yanray Wang62c99912023-05-11 11:06:53 +08001736static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001737{
1738 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1740 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1741 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1742 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1743 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1744};
1745
Yanray Wang62c99912023-05-11 11:06:53 +08001746static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001747{
1748 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1749 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001750 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1751 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1752 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1753 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1754
1755 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1756 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1757 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1758 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1759 0x20, 0x21, 0x22, 0x23 }
1760};
1761
Yanray Wang62c99912023-05-11 11:06:53 +08001762static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001763{
1764 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1765 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1766 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1767 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1768 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1769 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1770 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1771 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1772 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1773 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1774 0x25, 0xB2, 0x07, 0x2F }
1775};
1776
1777static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001778{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001779#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001780
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001781#if defined(MBEDTLS_CIPHER_MODE_XTS)
1782/*
1783 * AES-XTS test vectors from:
1784 *
1785 * IEEE P1619/D16 Annex B
1786 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1787 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1788 */
1789static const unsigned char aes_test_xts_key[][32] =
1790{
1791 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1795 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1796 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1797 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1798 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1799 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1800 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1801 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1802 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1803};
1804
1805static const unsigned char aes_test_xts_pt32[][32] =
1806{
1807 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1811 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1812 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1813 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1814 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1815 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1816 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1817 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1818 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1819};
1820
1821static const unsigned char aes_test_xts_ct32[][32] =
1822{
1823 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1824 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1825 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1826 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1827 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1828 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1829 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1830 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1831 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1832 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1833 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1834 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1835};
1836
1837static const unsigned char aes_test_xts_data_unit[][16] =
1838{
Gilles Peskine449bd832023-01-11 14:50:10 +01001839 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1841 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1843 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001845};
1846
1847#endif /* MBEDTLS_CIPHER_MODE_XTS */
1848
Paul Bakker5121ce52009-01-03 21:22:43 +00001849/*
1850 * Checkup routine
1851 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001852int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001853{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001854 int ret = 0, i, j, u, mode;
1855 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001856 unsigned char key[32];
1857 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001858 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001859#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1860 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001861 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001862#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001863#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001864 unsigned char prv[16];
1865#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001866#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1867 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001868 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001869#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001870#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001871 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001872#endif
1873#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001874 unsigned char nonce_counter[16];
1875 unsigned char stream_block[16];
1876#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001877 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
Gilles Peskine449bd832023-01-11 14:50:10 +01001879 memset(key, 0, 32);
1880 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001881
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001882 if (verbose != 0) {
1883#if defined(MBEDTLS_AES_ALT)
1884 mbedtls_printf(" AES note: alternative implementation.\n");
1885#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001886#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001887#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001888 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001889#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001890 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001891#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001892#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001893#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001894 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1895 mbedtls_printf(" AES note: using AESNI.\n");
1896 } else
1897#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001898#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001899 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1900 mbedtls_printf(" AES note: using VIA Padlock.\n");
1901 } else
1902#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001903#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001904 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001905 mbedtls_printf(" AES note: using AESCE.\n");
1906 } else
1907#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001908 {
1909#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1910 mbedtls_printf(" AES note: built-in implementation.\n");
1911#endif
1912 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001913#endif /* MBEDTLS_AES_ALT */
1914 }
1915
Paul Bakker5121ce52009-01-03 21:22:43 +00001916 /*
1917 * ECB mode
1918 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001919 {
1920 static const int num_tests =
1921 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001923 for (i = 0; i < num_tests << 1; i++) {
1924 u = i >> 1;
1925 keybits = 128 + u * 64;
1926 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001927
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001928 if (verbose != 0) {
1929 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1930 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1931 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001932
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001933 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001934
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001935 if (mode == MBEDTLS_AES_DECRYPT) {
1936 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1937 aes_tests = aes_test_ecb_dec[u];
1938 } else {
1939 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1940 aes_tests = aes_test_ecb_enc[u];
1941 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001942
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001943 /*
1944 * AES-192 is an optional feature that may be unavailable when
1945 * there is an alternative underlying implementation i.e. when
1946 * MBEDTLS_AES_ALT is defined.
1947 */
1948 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1949 mbedtls_printf("skipped\n");
1950 continue;
1951 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001952 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001953 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001954
1955 for (j = 0; j < 10000; j++) {
1956 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1957 if (ret != 0) {
1958 goto exit;
1959 }
1960 }
1961
1962 if (memcmp(buf, aes_tests, 16) != 0) {
1963 ret = 1;
1964 goto exit;
1965 }
1966
1967 if (verbose != 0) {
1968 mbedtls_printf("passed\n");
1969 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001970 }
1971
Gilles Peskine449bd832023-01-11 14:50:10 +01001972 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001973 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001974 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001975 }
1976
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001977#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001978 /*
1979 * CBC mode
1980 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001981 {
1982 static const int num_tests =
1983 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001984
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001985 for (i = 0; i < num_tests << 1; i++) {
1986 u = i >> 1;
1987 keybits = 128 + u * 64;
1988 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001989
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001990 if (verbose != 0) {
1991 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1992 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 }
1994
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001995 memset(iv, 0, 16);
1996 memset(prv, 0, 16);
1997 memset(buf, 0, 16);
1998
1999 if (mode == MBEDTLS_AES_DECRYPT) {
2000 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2001 aes_tests = aes_test_cbc_dec[u];
2002 } else {
2003 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2004 aes_tests = aes_test_cbc_enc[u];
2005 }
2006
2007 /*
2008 * AES-192 is an optional feature that may be unavailable when
2009 * there is an alternative underlying implementation i.e. when
2010 * MBEDTLS_AES_ALT is defined.
2011 */
2012 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2013 mbedtls_printf("skipped\n");
2014 continue;
2015 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002016 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002017 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002018
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002019 for (j = 0; j < 10000; j++) {
2020 if (mode == MBEDTLS_AES_ENCRYPT) {
2021 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002022
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002023 memcpy(tmp, prv, 16);
2024 memcpy(prv, buf, 16);
2025 memcpy(buf, tmp, 16);
2026 }
2027
2028 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2029 if (ret != 0) {
2030 goto exit;
2031 }
2032
2033 }
2034
2035 if (memcmp(buf, aes_tests, 16) != 0) {
2036 ret = 1;
2037 goto exit;
2038 }
2039
2040 if (verbose != 0) {
2041 mbedtls_printf("passed\n");
2042 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002043 }
2044
Gilles Peskine449bd832023-01-11 14:50:10 +01002045 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002046 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002047 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002049#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002050
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002051#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 /*
2053 * CFB128 mode
2054 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002055 {
2056 static const int num_tests =
2057 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002058
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002059 for (i = 0; i < num_tests << 1; i++) {
2060 u = i >> 1;
2061 keybits = 128 + u * 64;
2062 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002063
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002064 if (verbose != 0) {
2065 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2066 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2067 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002068
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002069 memcpy(iv, aes_test_cfb128_iv, 16);
2070 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002071
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002072 offset = 0;
2073 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2074 /*
2075 * AES-192 is an optional feature that may be unavailable when
2076 * there is an alternative underlying implementation i.e. when
2077 * MBEDTLS_AES_ALT is defined.
2078 */
2079 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2080 mbedtls_printf("skipped\n");
2081 continue;
2082 } else if (ret != 0) {
2083 goto exit;
2084 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002085
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002086 if (mode == MBEDTLS_AES_DECRYPT) {
2087 memcpy(buf, aes_test_cfb128_ct[u], 64);
2088 aes_tests = aes_test_cfb128_pt;
2089 } else {
2090 memcpy(buf, aes_test_cfb128_pt, 64);
2091 aes_tests = aes_test_cfb128_ct[u];
2092 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002093
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002094 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2095 if (ret != 0) {
2096 goto exit;
2097 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002098
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002099 if (memcmp(buf, aes_tests, 64) != 0) {
2100 ret = 1;
2101 goto exit;
2102 }
2103
2104 if (verbose != 0) {
2105 mbedtls_printf("passed\n");
2106 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002107 }
2108
Gilles Peskine449bd832023-01-11 14:50:10 +01002109 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002110 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002111 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002112 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002113#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002114
Simon Butcherad4e4932018-04-29 00:43:47 +01002115#if defined(MBEDTLS_CIPHER_MODE_OFB)
2116 /*
2117 * OFB mode
2118 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002119 {
2120 static const int num_tests =
2121 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002122
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002123 for (i = 0; i < num_tests << 1; i++) {
2124 u = i >> 1;
2125 keybits = 128 + u * 64;
2126 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002127
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002128 if (verbose != 0) {
2129 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2130 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2131 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002132
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002133 memcpy(iv, aes_test_ofb_iv, 16);
2134 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002135
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002136 offset = 0;
2137 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2138 /*
2139 * AES-192 is an optional feature that may be unavailable when
2140 * there is an alternative underlying implementation i.e. when
2141 * MBEDTLS_AES_ALT is defined.
2142 */
2143 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2144 mbedtls_printf("skipped\n");
2145 continue;
2146 } else if (ret != 0) {
2147 goto exit;
2148 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002149
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002150 if (mode == MBEDTLS_AES_DECRYPT) {
2151 memcpy(buf, aes_test_ofb_ct[u], 64);
2152 aes_tests = aes_test_ofb_pt;
2153 } else {
2154 memcpy(buf, aes_test_ofb_pt, 64);
2155 aes_tests = aes_test_ofb_ct[u];
2156 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002157
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002158 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2159 if (ret != 0) {
2160 goto exit;
2161 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002162
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002163 if (memcmp(buf, aes_tests, 64) != 0) {
2164 ret = 1;
2165 goto exit;
2166 }
2167
2168 if (verbose != 0) {
2169 mbedtls_printf("passed\n");
2170 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002171 }
2172
Gilles Peskine449bd832023-01-11 14:50:10 +01002173 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002174 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002175 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002176 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002177#endif /* MBEDTLS_CIPHER_MODE_OFB */
2178
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002179#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002180 /*
2181 * CTR mode
2182 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002183 {
2184 static const int num_tests =
2185 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002186
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002187 for (i = 0; i < num_tests << 1; i++) {
2188 u = i >> 1;
2189 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002190
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002191 if (verbose != 0) {
2192 mbedtls_printf(" AES-CTR-128 (%s): ",
2193 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2194 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2197 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002198
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002199 offset = 0;
2200 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2201 goto exit;
2202 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002203
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002204 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002205
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002206 if (mode == MBEDTLS_AES_DECRYPT) {
2207 memcpy(buf, aes_test_ctr_ct[u], len);
2208 aes_tests = aes_test_ctr_pt[u];
2209 } else {
2210 memcpy(buf, aes_test_ctr_pt[u], len);
2211 aes_tests = aes_test_ctr_ct[u];
2212 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002213
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002214 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2215 stream_block, buf, buf);
2216 if (ret != 0) {
2217 goto exit;
2218 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002219
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002220 if (memcmp(buf, aes_tests, len) != 0) {
2221 ret = 1;
2222 goto exit;
2223 }
2224
2225 if (verbose != 0) {
2226 mbedtls_printf("passed\n");
2227 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002228 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002229 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002230
Gilles Peskine449bd832023-01-11 14:50:10 +01002231 if (verbose != 0) {
2232 mbedtls_printf("\n");
2233 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002234#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002235
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002236#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002237 /*
2238 * XTS mode
2239 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002240 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002241 static const int num_tests =
2242 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2243 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002244
Gilles Peskine449bd832023-01-11 14:50:10 +01002245 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 for (i = 0; i < num_tests << 1; i++) {
2248 const unsigned char *data_unit;
2249 u = i >> 1;
2250 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002251
Gilles Peskine449bd832023-01-11 14:50:10 +01002252 if (verbose != 0) {
2253 mbedtls_printf(" AES-XTS-128 (%s): ",
2254 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2255 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002256
Gilles Peskine449bd832023-01-11 14:50:10 +01002257 memset(key, 0, sizeof(key));
2258 memcpy(key, aes_test_xts_key[u], 32);
2259 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002260
Gilles Peskine449bd832023-01-11 14:50:10 +01002261 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002262
Gilles Peskine449bd832023-01-11 14:50:10 +01002263 if (mode == MBEDTLS_AES_DECRYPT) {
2264 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2265 if (ret != 0) {
2266 goto exit;
2267 }
2268 memcpy(buf, aes_test_xts_ct32[u], len);
2269 aes_tests = aes_test_xts_pt32[u];
2270 } else {
2271 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2272 if (ret != 0) {
2273 goto exit;
2274 }
2275 memcpy(buf, aes_test_xts_pt32[u], len);
2276 aes_tests = aes_test_xts_ct32[u];
2277 }
2278
2279
2280 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2281 buf, buf);
2282 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002283 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002284 }
2285
2286 if (memcmp(buf, aes_tests, len) != 0) {
2287 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002288 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002289 }
2290
2291 if (verbose != 0) {
2292 mbedtls_printf("passed\n");
2293 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002294 }
2295
Gilles Peskine449bd832023-01-11 14:50:10 +01002296 if (verbose != 0) {
2297 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002298 }
2299
Gilles Peskine449bd832023-01-11 14:50:10 +01002300 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002301 }
2302#endif /* MBEDTLS_CIPHER_MODE_XTS */
2303
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002304 ret = 0;
2305
2306exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002307 if (ret != 0 && verbose != 0) {
2308 mbedtls_printf("failed\n");
2309 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002310
Gilles Peskine449bd832023-01-11 14:50:10 +01002311 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002312
Gilles Peskine449bd832023-01-11 14:50:10 +01002313 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002314}
2315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002316#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002317
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002318#endif /* MBEDTLS_AES_C */