blob: 6ee9971d887316241ee5612c94027cb0c5421fd3 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Jerry Yuba42b072023-08-10 12:53:26 +080037#if defined(__aarch64__)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yue62ff092023-08-16 14:15:00 +080043#if defined(__amd64__) || defined(__x86_64__) || \
44 defined(_M_X64) || defined(_M_AMD64)
Jerry Yu02b15192023-04-23 14:43:19 +080045#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080046#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080047#endif
48#endif
49
Jerry Yue62ff092023-08-16 14:15:00 +080050#if defined(__i386__) || defined(_M_IX86)
51#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
52#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080053#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080054
55#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
56#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
57#endif
Jerry Yu02b15192023-04-23 14:43:19 +080058#endif
59
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020060#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000061#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000062#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020063#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000064#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010065#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080066#if defined(MBEDTLS_AESCE_C)
67#include "aesce.h"
68#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000069
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000070#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010071
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020073
Jerry Yu516cf272023-08-16 17:33:32 +080074#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) && defined(__GNUC__)
Paul Bakker048d04e2012-02-12 17:31:04 +000075static int aes_padlock_ace = -1;
76#endif
77
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000079/*
80 * Forward S-box
81 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010082#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
83 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000084static const unsigned char FSb[256] =
85{
86 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
87 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
88 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
89 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
90 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
91 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
92 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
93 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
94 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
95 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
96 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
97 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
98 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
99 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
100 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
101 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
102 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
103 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
104 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
105 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
106 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
107 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
108 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
109 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
110 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
111 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
112 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
113 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
114 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
115 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
116 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
117 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
118};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100119#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
120 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000121
122/*
123 * Forward tables
124 */
125#define FT \
126\
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
128 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
129 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
130 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
131 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
132 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
133 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
134 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
135 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
136 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
137 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
138 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
139 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
140 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
141 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
142 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
143 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
144 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
145 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
146 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
147 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
148 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
149 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
150 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
151 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
152 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
153 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
154 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
155 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
156 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
157 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
158 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
159 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
160 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
161 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
162 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
163 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
164 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
165 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
166 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
167 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
168 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
169 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
170 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
171 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
172 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
173 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
174 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
175 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
176 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
177 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
178 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
179 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
180 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
181 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
182 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
183 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
184 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
185 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
186 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
187 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
188 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
189 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
190 V(CB, B0, B0, 7B), V(FC, 54, 54, A8), V(D6, BB, BB, 6D), V(3A, 16, 16, 2C)
Paul Bakker5121ce52009-01-03 21:22:43 +0000191
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100192#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100193#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000194static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000195#undef V
196
Hanno Beckerad049a92017-06-19 16:31:54 +0100197#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000201#undef V
202
Gilles Peskine449bd832023-01-11 14:50:10 +0100203#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000204static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000205#undef V
206
Gilles Peskine449bd832023-01-11 14:50:10 +0100207#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000208static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000209#undef V
210
Hanno Becker177d3cf2017-06-07 15:52:48 +0100211#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200212
Dave Rodgman1be24632023-06-29 12:01:24 +0100213#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
214
Paul Bakker5121ce52009-01-03 21:22:43 +0000215#undef FT
216
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100217#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000218/*
219 * Reverse S-box
220 */
221static const unsigned char RSb[256] =
222{
223 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
224 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
225 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
226 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
227 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
228 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
229 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
230 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
231 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
232 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
233 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
234 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
235 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
236 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
237 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
238 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
239 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
240 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
241 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
242 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
243 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
244 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
245 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
246 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
247 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
248 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
249 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
250 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
251 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
252 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
253 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
254 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
255};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100256#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258/*
259 * Reverse tables
260 */
261#define RT \
262\
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
264 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
265 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
266 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
267 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
268 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
269 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
270 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
271 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
272 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
273 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
274 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
275 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
276 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
277 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
278 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
279 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
280 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
281 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
282 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
283 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
284 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
285 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
286 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
287 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
288 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
289 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
290 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
291 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
292 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
293 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
294 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
295 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
296 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
297 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
298 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
299 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
300 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
301 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
302 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
303 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
304 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
305 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
306 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
307 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
308 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
309 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
310 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
311 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
312 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
313 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
314 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
315 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
316 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
317 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
318 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
319 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
320 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
321 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
322 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
323 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
324 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
325 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
326 V(61, 84, CB, 7B), V(70, B6, 32, D5), V(74, 5C, 6C, 48), V(42, 57, B8, D0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000327
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100328#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
329
Gilles Peskine449bd832023-01-11 14:50:10 +0100330#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000331static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000332#undef V
333
Hanno Beckerad049a92017-06-19 16:31:54 +0100334#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000338#undef V
339
Gilles Peskine449bd832023-01-11 14:50:10 +0100340#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000341static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000342#undef V
343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000345static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000346#undef V
347
Hanno Becker177d3cf2017-06-07 15:52:48 +0100348#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200349
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800350#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
351
Paul Bakker5121ce52009-01-03 21:22:43 +0000352#undef RT
353
Dave Rodgman34152a42023-06-27 18:31:24 +0100354#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000355/*
356 * Round constants
357 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000358static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000359{
360 0x00000001, 0x00000002, 0x00000004, 0x00000008,
361 0x00000010, 0x00000020, 0x00000040, 0x00000080,
362 0x0000001B, 0x00000036
363};
Dave Rodgman34152a42023-06-27 18:31:24 +0100364#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000367
368/*
369 * Forward S-box & tables
370 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100371#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
372 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000373static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100374#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
375 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100376#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200377static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100378#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200379static uint32_t FT1[256];
380static uint32_t FT2[256];
381static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100382#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100383#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000384
385/*
386 * Reverse S-box & tables
387 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100388#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000389static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100390#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100391
392#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000393static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100394#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000395static uint32_t RT1[256];
396static uint32_t RT2[256];
397static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100398#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100399#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
Dave Rodgman8c753f92023-06-27 18:16:13 +0100401#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000402/*
403 * Round constants
404 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000405static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
407/*
408 * Tables generation code
409 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100410#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
411#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
412#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
414static int aes_init_done = 0;
415
Gilles Peskine449bd832023-01-11 14:50:10 +0100416static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000417{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800418 int i;
419 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800420 uint8_t pow[256];
421 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
423 /*
424 * compute pow and log tables over GF(2^8)
425 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800428 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800429 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 }
431
432 /*
433 * calculate the round constants
434 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800436 RCON[i] = x;
437 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 }
439
440 /*
441 * generate the forward and reverse S-boxes
442 */
443 FSb[0x00] = 0x63;
444 RSb[0x63] = 0x00;
445
Gilles Peskine449bd832023-01-11 14:50:10 +0100446 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000447 x = pow[255 - log[i]];
448
Yanray Wangfe944ce2023-06-26 18:16:01 +0800449 y = x; y = (y << 1) | (y >> 7);
450 x ^= y; y = (y << 1) | (y >> 7);
451 x ^= y; y = (y << 1) | (y >> 7);
452 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 x ^= y ^ 0x63;
454
Yanray Wangfe944ce2023-06-26 18:16:01 +0800455 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 RSb[x] = (unsigned char) i;
457 }
458
459 /*
460 * generate the forward and reverse tables
461 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800464 y = XTIME(x);
465 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000466
Gilles Peskine449bd832023-01-11 14:50:10 +0100467 FT0[i] = ((uint32_t) y) ^
468 ((uint32_t) x << 8) ^
469 ((uint32_t) x << 16) ^
470 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
Hanno Beckerad049a92017-06-19 16:31:54 +0100472#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 FT1[i] = ROTL8(FT0[i]);
474 FT2[i] = ROTL8(FT1[i]);
475 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100476#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
478 x = RSb[i];
479
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100480#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
482 ((uint32_t) MUL(0x09, x) << 8) ^
483 ((uint32_t) MUL(0x0D, x) << 16) ^
484 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
Hanno Beckerad049a92017-06-19 16:31:54 +0100486#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 RT1[i] = ROTL8(RT0[i]);
488 RT2[i] = ROTL8(RT1[i]);
489 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100490#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100491#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000492 }
493}
494
Dave Rodgman8c753f92023-06-27 18:16:13 +0100495#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
496
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200497#undef ROTL8
498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000500
Hanno Beckerad049a92017-06-19 16:31:54 +0100501#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
504#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
505#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200506
507#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100508#define AES_RT1(idx) ROTL8(RT0[idx])
509#define AES_RT2(idx) ROTL16(RT0[idx])
510#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200511
512#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100513#define AES_FT1(idx) ROTL8(FT0[idx])
514#define AES_FT2(idx) ROTL16(FT0[idx])
515#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200516
Hanno Becker177d3cf2017-06-07 15:52:48 +0100517#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200518
519#define AES_RT0(idx) RT0[idx]
520#define AES_RT1(idx) RT1[idx]
521#define AES_RT2(idx) RT2[idx]
522#define AES_RT3(idx) RT3[idx]
523
524#define AES_FT0(idx) FT0[idx]
525#define AES_FT1(idx) FT1[idx]
526#define AES_FT2(idx) FT2[idx]
527#define AES_FT3(idx) FT3[idx]
528
Hanno Becker177d3cf2017-06-07 15:52:48 +0100529#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200532{
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200534}
535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200537{
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200539 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100540 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200543}
544
Jaeden Amero9366feb2018-05-29 18:55:17 +0100545#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100546void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100547{
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 mbedtls_aes_init(&ctx->crypt);
549 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100550}
551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100553{
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100555 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100556 }
Simon Butcher5201e412018-12-06 17:40:14 +0000557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 mbedtls_aes_free(&ctx->crypt);
559 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100560}
561#endif /* MBEDTLS_CIPHER_MODE_XTS */
562
Gilles Peskine0de8f852023-03-16 17:14:59 +0100563/* Some implementations need the round keys to be aligned.
564 * Return an offset to be added to buf, such that (buf + offset) is
565 * correctly aligned.
566 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
567 * i.e. an offset of 1 means 4 bytes and so on.
568 */
569#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100570 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100571#define MAY_NEED_TO_ALIGN
572#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100573
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100574#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
575 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100576static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
577{
578#if defined(MAY_NEED_TO_ALIGN)
579 int align_16_bytes = 0;
580
Jerry Yu516cf272023-08-16 17:33:32 +0800581#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) && defined(__GNUC__)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100582 if (aes_padlock_ace == -1) {
583 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
584 }
585 if (aes_padlock_ace) {
586 align_16_bytes = 1;
587 }
588#endif
589
Gilles Peskine9c682e72023-03-16 17:21:33 +0100590#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100591 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
592 align_16_bytes = 1;
593 }
594#endif
595
596 if (align_16_bytes) {
597 /* These implementations needs 16-byte alignment
598 * for the round key array. */
599 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
600 if (delta == 0) {
601 return 0;
602 } else {
603 return 4 - delta; // 16 bytes = 4 uint32_t
604 }
605 }
606#else /* MAY_NEED_TO_ALIGN */
607 (void) buf;
608#endif /* MAY_NEED_TO_ALIGN */
609
610 return 0;
611}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100612#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
613 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100614
Paul Bakker5121ce52009-01-03 21:22:43 +0000615/*
616 * AES key schedule (encryption)
617 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200618#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100619int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
620 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000621{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800622#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Paul Bakker23986e52011-04-24 08:57:21 +0000623 unsigned int i;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800624#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000625 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800629#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 case 192: ctx->nr = 12; break;
631 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800632#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635
Simon Butcher5201e412018-12-06 17:40:14 +0000636#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000638 aes_gen_tables();
639 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000640 }
641#endif
642
Gilles Peskine0de8f852023-03-16 17:14:59 +0100643 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100644 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000645
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100646#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
648 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
649 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100650#endif
651
Jerry Yu3f2fb712023-01-10 17:05:42 +0800652#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
653 if (mbedtls_aesce_has_support()) {
654 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
655 }
656#endif
657
Jerry Yucc068ae2023-08-16 16:07:57 +0800658/* When runtime detection enabled and plain C is disabled, compiler
659 reports `-Werror=return-type`. */
660#if defined(MBEDTLS_HAVE_X86) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && \
661 defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_AESNI_HAVE_CODE)
662 return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
663#endif
664
Jerry Yu29c91ba2023-08-04 11:02:04 +0800665#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 for (i = 0; i < (keybits >> 5); i++) {
667 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000668 }
669
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000671 case 10:
672
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
676 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
677 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
678 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
680 RK[5] = RK[1] ^ RK[4];
681 RK[6] = RK[2] ^ RK[5];
682 RK[7] = RK[3] ^ RK[6];
683 }
684 break;
685
Arto Kinnunen732ca322023-04-14 14:26:10 +0800686#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000687 case 12:
688
Gilles Peskine449bd832023-01-11 14:50:10 +0100689 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000690 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
692 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
693 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
694 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
696 RK[7] = RK[1] ^ RK[6];
697 RK[8] = RK[2] ^ RK[7];
698 RK[9] = RK[3] ^ RK[8];
699 RK[10] = RK[4] ^ RK[9];
700 RK[11] = RK[5] ^ RK[10];
701 }
702 break;
703
704 case 14:
705
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000707 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
709 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
710 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
711 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000712
713 RK[9] = RK[1] ^ RK[8];
714 RK[10] = RK[2] ^ RK[9];
715 RK[11] = RK[3] ^ RK[10];
716
717 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
719 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
720 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
721 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
723 RK[13] = RK[5] ^ RK[12];
724 RK[14] = RK[6] ^ RK[13];
725 RK[15] = RK[7] ^ RK[14];
726 }
727 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800728#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000729 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000730
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800732#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000733}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200734#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000735
736/*
737 * AES key schedule (decryption)
738 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200739#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100740int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
741 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000742{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800743#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
744 int i, j;
745 uint32_t *SK;
746#endif
747 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200748 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000749 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800750
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200751
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
Gilles Peskine0de8f852023-03-16 17:14:59 +0100754 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100755 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000756
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200757 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200759 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000761
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200762 ctx->nr = cty.nr;
763
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100764#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
766 mbedtls_aesni_inverse_key((unsigned char *) RK,
767 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200768 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100769 }
770#endif
771
Jerry Yue096da12023-01-10 17:07:01 +0800772#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
773 if (mbedtls_aesce_has_support()) {
774 mbedtls_aesce_inverse_key(
775 (unsigned char *) RK,
776 (const unsigned char *) (cty.buf + cty.rk_offset),
777 ctx->nr);
778 goto exit;
779 }
780#endif
781
Jerry Yu29c91ba2023-08-04 11:02:04 +0800782#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100783 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000784
785 *RK++ = *SK++;
786 *RK++ = *SK++;
787 *RK++ = *SK++;
788 *RK++ = *SK++;
789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
791 for (j = 0; j < 4; j++, SK++) {
792 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
793 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
794 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
795 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000796 }
797 }
798
799 *RK++ = *SK++;
800 *RK++ = *SK++;
801 *RK++ = *SK++;
802 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800803#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200804exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000806
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000808}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100809#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100810
811#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100812static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
813 unsigned int keybits,
814 const unsigned char **key1,
815 unsigned int *key1bits,
816 const unsigned char **key2,
817 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818{
819 const unsigned int half_keybits = keybits / 2;
820 const unsigned int half_keybytes = half_keybits / 8;
821
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100823 case 256: break;
824 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100825 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100826 }
827
828 *key1bits = half_keybits;
829 *key2bits = half_keybits;
830 *key1 = &key[0];
831 *key2 = &key[half_keybytes];
832
833 return 0;
834}
835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
837 const unsigned char *key,
838 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100839{
Janos Follath24eed8d2019-11-22 13:21:35 +0000840 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100841 const unsigned char *key1, *key2;
842 unsigned int key1bits, key2bits;
843
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
845 &key2, &key2bits);
846 if (ret != 0) {
847 return ret;
848 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100849
850 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
852 if (ret != 0) {
853 return ret;
854 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100855
856 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100858}
859
Gilles Peskine449bd832023-01-11 14:50:10 +0100860int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
861 const unsigned char *key,
862 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100863{
Janos Follath24eed8d2019-11-22 13:21:35 +0000864 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100865 const unsigned char *key1, *key2;
866 unsigned int key1bits, key2bits;
867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
869 &key2, &key2bits);
870 if (ret != 0) {
871 return ret;
872 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100873
874 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
876 if (ret != 0) {
877 return ret;
878 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100879
880 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100882}
883#endif /* MBEDTLS_CIPHER_MODE_XTS */
884
Gilles Peskine449bd832023-01-11 14:50:10 +0100885#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100886 do \
887 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
889 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
890 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
891 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100892 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
894 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
895 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
896 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100897 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
899 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
900 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
901 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100902 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
904 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
905 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
906 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
907 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
Gilles Peskine449bd832023-01-11 14:50:10 +0100909#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100910 do \
911 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
913 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
914 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
915 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100916 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
918 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
919 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
920 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100921 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
923 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
924 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
925 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100926 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
928 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
929 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
930 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
931 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000932
933/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934 * AES-ECB block encryption
935 */
936#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100937int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
938 const unsigned char input[16],
939 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200940{
941 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100942 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200944 uint32_t X[4];
945 uint32_t Y[4];
946 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
949 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
950 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
951 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
954 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]);
955 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 +0200956 }
957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 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 +0200959
Gilles Peskine5197c662020-08-26 17:03:24 +0200960 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200965
Gilles Peskine5197c662020-08-26 17:03:24 +0200966 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200971
Gilles Peskine5197c662020-08-26 17:03:24 +0200972 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
974 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
975 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200977
Gilles Peskine5197c662020-08-26 17:03:24 +0200978 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
980 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
981 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
982 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
985 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
986 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
987 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000988
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992}
993#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
994
995/*
996 * AES-ECB block decryption
997 */
998#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100999int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
1000 const unsigned char input[16],
1001 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001002{
1003 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +01001004 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001006 uint32_t X[4];
1007 uint32_t Y[4];
1008 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1011 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1012 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1013 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1016 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]);
1017 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 +02001018 }
1019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 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 +02001021
Gilles Peskine5197c662020-08-26 17:03:24 +02001022 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001027
Gilles Peskine5197c662020-08-26 17:03:24 +02001028 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001033
Gilles Peskine5197c662020-08-26 17:03:24 +02001034 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1036 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1037 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001039
Gilles Peskine5197c662020-08-26 17:03:24 +02001040 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1042 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1043 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1044 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1047 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1048 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1049 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001050
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001054}
1055#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1056
Gilles Peskine0de8f852023-03-16 17:14:59 +01001057#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001058/* VIA Padlock and our intrinsics-based implementation of AESNI require
1059 * the round keys to be aligned on a 16-byte boundary. We take care of this
1060 * before creating them, but the AES context may have moved (this can happen
1061 * if the library is called from a language with managed memory), and in later
1062 * calls it might have a different alignment with respect to 16-byte memory.
1063 * So we may need to realign.
1064 */
1065static void aes_maybe_realign(mbedtls_aes_context *ctx)
1066{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001067 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1068 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001069 memmove(ctx->buf + new_offset, // new address
1070 ctx->buf + ctx->rk_offset, // current address
1071 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1072 ctx->rk_offset = new_offset;
1073 }
1074}
1075#endif
1076
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001077/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001078 * AES-ECB block encryption/decryption
1079 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001080int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1081 int mode,
1082 const unsigned char input[16],
1083 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001084{
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001086 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001088
Gilles Peskine0de8f852023-03-16 17:14:59 +01001089#if defined(MAY_NEED_TO_ALIGN)
1090 aes_maybe_realign(ctx);
1091#endif
1092
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001093#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1095 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1096 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001097#endif
1098
Jerry Yu2bb3d812023-01-10 17:38:26 +08001099#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1100 if (mbedtls_aesce_has_support()) {
1101 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1102 }
1103#endif
1104
Jerry Yu516cf272023-08-16 17:33:32 +08001105#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) && defined(__GNUC__)
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001107 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001108 }
1109#endif
1110
Jerry Yucc068ae2023-08-16 16:07:57 +08001111/* When runtime detection enabled and plain C is disabled, compiler
1112 reports `-Werror=return-type`. */
1113#if defined(MBEDTLS_HAVE_X86) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && \
1114 defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_AESNI_HAVE_CODE)
1115 return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
1116#endif
1117
Jerry Yu29c91ba2023-08-04 11:02:04 +08001118#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 if (mode == MBEDTLS_AES_ENCRYPT) {
1120 return mbedtls_internal_aes_encrypt(ctx, input, output);
1121 } else {
1122 return mbedtls_internal_aes_decrypt(ctx, input, output);
1123 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001124#endif
1125
Paul Bakker5121ce52009-01-03 21:22:43 +00001126}
1127
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001128#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001129
Paul Bakker5121ce52009-01-03 21:22:43 +00001130/*
1131 * AES-CBC buffer encryption/decryption
1132 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001133int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1134 int mode,
1135 size_t length,
1136 unsigned char iv[16],
1137 const unsigned char *input,
1138 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001139{
Gilles Peskine7820a572021-07-07 21:08:28 +02001140 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001141 unsigned char temp[16];
1142
Gilles Peskine449bd832023-01-11 14:50:10 +01001143 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001144 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001146
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 if (length % 16) {
1148 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1149 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001150
Jerry Yu516cf272023-08-16 17:33:32 +08001151#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) && defined(__GNUC__)
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 if (aes_padlock_ace > 0) {
1153 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1154 return 0;
1155 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001156
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001157 // If padlock data misaligned, we just fall back to
1158 // unaccelerated mode
1159 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001160 }
1161#endif
1162
Dave Rodgman906c63c2023-06-14 17:53:51 +01001163 const unsigned char *ivp = iv;
1164
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 if (mode == MBEDTLS_AES_DECRYPT) {
1166 while (length > 0) {
1167 memcpy(temp, input, 16);
1168 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1169 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001170 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001172 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001173 * the result for the next block in CBC, and the cost of transferring that data from
1174 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001175 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001176
Gilles Peskine449bd832023-01-11 14:50:10 +01001177 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001178
1179 input += 16;
1180 output += 16;
1181 length -= 16;
1182 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 } else {
1184 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001185 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001186
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1188 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001189 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001191 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001192
1193 input += 16;
1194 output += 16;
1195 length -= 16;
1196 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001197 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001198 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001199 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001200
Gilles Peskine7820a572021-07-07 21:08:28 +02001201exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001203}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001205
Aorimn5f778012016-06-09 23:22:58 +02001206#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001207
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001208typedef unsigned char mbedtls_be128[16];
1209
1210/*
1211 * GF(2^128) multiplication function
1212 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001213 * This function multiplies a field element by x in the polynomial field
1214 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001215 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001216 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001217 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001218#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001219MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001220#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001221static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001222 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001223{
1224 uint64_t a, b, ra, rb;
1225
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 a = MBEDTLS_GET_UINT64_LE(x, 0);
1227 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001228
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1230 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001231
Gilles Peskine449bd832023-01-11 14:50:10 +01001232 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1233 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001234}
1235
Aorimn5f778012016-06-09 23:22:58 +02001236/*
1237 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001238 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001239 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001240 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001241 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001242#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001243MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001244#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001245int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1246 int mode,
1247 size_t length,
1248 const unsigned char data_unit[16],
1249 const unsigned char *input,
1250 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001251{
Janos Follath24eed8d2019-11-22 13:21:35 +00001252 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253 size_t blocks = length / 16;
1254 size_t leftover = length % 16;
1255 unsigned char tweak[16];
1256 unsigned char prev_tweak[16];
1257 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001258
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001260 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001262
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001263 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001266 }
Aorimn5f778012016-06-09 23:22:58 +02001267
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001268 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001270 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 }
Aorimn5f778012016-06-09 23:22:58 +02001272
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1275 data_unit, tweak);
1276 if (ret != 0) {
1277 return ret;
1278 }
Aorimn5f778012016-06-09 23:22:58 +02001279
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001281 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282 /* We are on the last block in a decrypt operation that has
1283 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001284 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285 * the leftovers and then update the current tweak for use on this,
1286 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 memcpy(prev_tweak, tweak, sizeof(tweak));
1288 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289 }
1290
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001292
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1294 if (ret != 0) {
1295 return ret;
1296 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001297
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001299
1300 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001301 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001302
1303 output += 16;
1304 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001305 }
1306
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001308 /* If we are on the leftover bytes in a decrypt operation, we need to
1309 * use the previous tweak for these bytes (as saved in prev_tweak). */
1310 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001311
Jaeden Amerod82cd862018-04-28 15:02:45 +01001312 /* We are now on the final part of the data unit, which doesn't divide
1313 * evenly by 16. It's time for ciphertext stealing. */
1314 size_t i;
1315 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001316
Jaeden Amerod82cd862018-04-28 15:02:45 +01001317 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001318 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001319 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001320 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001321 }
Aorimn5f778012016-06-09 23:22:58 +02001322
Dave Rodgman069e7f42022-11-24 19:37:26 +00001323 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001325
Jaeden Amerod82cd862018-04-28 15:02:45 +01001326 /* Copy ciphertext bytes from the previous block for input in this
1327 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001329
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1331 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001332 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 }
Aorimn5f778012016-06-09 23:22:58 +02001334
Jaeden Amerod82cd862018-04-28 15:02:45 +01001335 /* Write the result back to the previous block, overriding the previous
1336 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001337 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001338 }
1339
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001341}
1342#endif /* MBEDTLS_CIPHER_MODE_XTS */
1343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001344#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001345/*
1346 * AES-CFB128 buffer encryption/decryption
1347 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001348int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1349 int mode,
1350 size_t length,
1351 size_t *iv_off,
1352 unsigned char iv[16],
1353 const unsigned char *input,
1354 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001355{
Paul Bakker27fdf462011-06-09 13:55:13 +00001356 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001357 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001358 size_t n;
1359
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001361 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001363
1364 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001365
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 if (n > 15) {
1367 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1368 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001369
Gilles Peskine449bd832023-01-11 14:50:10 +01001370 if (mode == MBEDTLS_AES_DECRYPT) {
1371 while (length--) {
1372 if (n == 0) {
1373 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1374 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001375 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001377 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001378
1379 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001381 iv[n] = (unsigned char) c;
1382
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001384 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 } else {
1386 while (length--) {
1387 if (n == 0) {
1388 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1389 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001390 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001392 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001393
Gilles Peskine449bd832023-01-11 14:50:10 +01001394 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001395
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001397 }
1398 }
1399
1400 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001401 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001402
Gilles Peskine7820a572021-07-07 21:08:28 +02001403exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001404 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001405}
Paul Bakker556efba2014-01-24 15:38:12 +01001406
1407/*
1408 * AES-CFB8 buffer encryption/decryption
1409 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001410int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1411 int mode,
1412 size_t length,
1413 unsigned char iv[16],
1414 const unsigned char *input,
1415 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001416{
Gilles Peskine7820a572021-07-07 21:08:28 +02001417 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001418 unsigned char c;
1419 unsigned char ov[17];
1420
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001422 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 }
1424 while (length--) {
1425 memcpy(ov, iv, 16);
1426 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1427 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001428 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 }
Paul Bakker556efba2014-01-24 15:38:12 +01001430
Gilles Peskine449bd832023-01-11 14:50:10 +01001431 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001432 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 }
Paul Bakker556efba2014-01-24 15:38:12 +01001434
Gilles Peskine449bd832023-01-11 14:50:10 +01001435 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001436
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001438 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001439 }
Paul Bakker556efba2014-01-24 15:38:12 +01001440
Gilles Peskine449bd832023-01-11 14:50:10 +01001441 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001442 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001443 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001444
Gilles Peskine7820a572021-07-07 21:08:28 +02001445exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001446 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001447}
Simon Butcher76a5b222018-04-22 22:57:27 +01001448#endif /* MBEDTLS_CIPHER_MODE_CFB */
1449
1450#if defined(MBEDTLS_CIPHER_MODE_OFB)
1451/*
1452 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1453 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001454int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1455 size_t length,
1456 size_t *iv_off,
1457 unsigned char iv[16],
1458 const unsigned char *input,
1459 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001460{
Simon Butcherad4e4932018-04-29 00:43:47 +01001461 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001462 size_t n;
1463
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001464 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001465
Gilles Peskine449bd832023-01-11 14:50:10 +01001466 if (n > 15) {
1467 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1468 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001469
Gilles Peskine449bd832023-01-11 14:50:10 +01001470 while (length--) {
1471 if (n == 0) {
1472 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1473 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001474 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001475 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001476 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001477 *output++ = *input++ ^ iv[n];
1478
Gilles Peskine449bd832023-01-11 14:50:10 +01001479 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001480 }
1481
1482 *iv_off = n;
1483
Simon Butcherad4e4932018-04-29 00:43:47 +01001484exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001485 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001486}
1487#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001490/*
1491 * AES-CTR buffer encryption/decryption
1492 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001493int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1494 size_t length,
1495 size_t *nc_off,
1496 unsigned char nonce_counter[16],
1497 unsigned char stream_block[16],
1498 const unsigned char *input,
1499 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001500{
Paul Bakker369e14b2012-04-18 14:16:09 +00001501 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001502 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001503 size_t n;
1504
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001505 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001506
Gilles Peskine449bd832023-01-11 14:50:10 +01001507 if (n > 0x0F) {
1508 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1509 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001510
Gilles Peskine449bd832023-01-11 14:50:10 +01001511 while (length--) {
1512 if (n == 0) {
1513 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1514 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001515 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001516 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001517
Gilles Peskine449bd832023-01-11 14:50:10 +01001518 for (i = 16; i > 0; i--) {
1519 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001520 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001521 }
1522 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001523 }
1524 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001525 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001526
Gilles Peskine449bd832023-01-11 14:50:10 +01001527 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001528 }
1529
1530 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001531 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001532
Gilles Peskine7820a572021-07-07 21:08:28 +02001533exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001534 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001535}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001536#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001537
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001538#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001540#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001541/*
1542 * AES test vectors from:
1543 *
1544 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1545 */
Yanray Wang62c99912023-05-11 11:06:53 +08001546static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001547{
1548 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1549 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001550#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001551 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1552 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1553 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1554 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001555#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001556};
1557
Yanray Wang62c99912023-05-11 11:06:53 +08001558static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001559{
1560 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1561 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001562#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001563 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1564 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1565 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1566 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001567#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001568};
1569
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001570#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001571static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001572{
1573 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1574 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001575#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001576 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1577 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1578 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1579 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001580#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001581};
1582
Yanray Wang62c99912023-05-11 11:06:53 +08001583static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001584{
1585 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1586 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001587#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001588 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1589 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1590 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1591 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001592#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001593};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001594#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001595
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001596#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001597/*
1598 * AES-CFB128 test vectors from:
1599 *
1600 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1601 */
Yanray Wang62c99912023-05-11 11:06:53 +08001602static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001603{
1604 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1605 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001606#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001607 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1608 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1609 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1610 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1611 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1612 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1613 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001614#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001615};
1616
1617static const unsigned char aes_test_cfb128_iv[16] =
1618{
1619 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1620 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1621};
1622
1623static const unsigned char aes_test_cfb128_pt[64] =
1624{
1625 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1626 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1627 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1628 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1629 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1630 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1631 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1632 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1633};
1634
Yanray Wang62c99912023-05-11 11:06:53 +08001635static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001636{
1637 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1638 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1639 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1640 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1641 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1642 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1643 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1644 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001645#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001646 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1647 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1648 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1649 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1650 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1651 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1652 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1653 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1654 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1655 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1656 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1657 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1658 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1659 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1660 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1661 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001662#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001663};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001664#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001665
Simon Butcherad4e4932018-04-29 00:43:47 +01001666#if defined(MBEDTLS_CIPHER_MODE_OFB)
1667/*
1668 * AES-OFB test vectors from:
1669 *
Simon Butcher5db13622018-06-04 22:11:25 +01001670 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001671 */
Yanray Wang62c99912023-05-11 11:06:53 +08001672static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001673{
1674 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1675 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001676#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001677 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1678 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1679 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1680 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1681 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1682 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1683 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001684#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001685};
1686
1687static const unsigned char aes_test_ofb_iv[16] =
1688{
1689 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1690 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1691};
1692
1693static const unsigned char aes_test_ofb_pt[64] =
1694{
1695 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1696 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1697 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1698 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1699 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1700 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1701 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1702 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1703};
1704
Yanray Wang62c99912023-05-11 11:06:53 +08001705static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001706{
1707 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1708 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1709 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1710 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1711 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1712 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1713 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1714 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001715#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001716 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1717 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1718 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1719 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1720 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1721 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1722 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1723 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1724 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1725 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1726 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1727 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1728 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1729 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1730 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1731 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001732#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001733};
1734#endif /* MBEDTLS_CIPHER_MODE_OFB */
1735
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001736#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001737/*
1738 * AES-CTR test vectors from:
1739 *
1740 * http://www.faqs.org/rfcs/rfc3686.html
1741 */
1742
Yanray Wang62c99912023-05-11 11:06:53 +08001743static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001744{
1745 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1746 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1747 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1748 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1749 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1750 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1751};
1752
Yanray Wang62c99912023-05-11 11:06:53 +08001753static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001754{
1755 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1757 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1758 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1759 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1760 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1761};
1762
Yanray Wang62c99912023-05-11 11:06:53 +08001763static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001764{
1765 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1766 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001767 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1768 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1769 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1770 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1771
1772 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1773 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1774 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1775 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1776 0x20, 0x21, 0x22, 0x23 }
1777};
1778
Yanray Wang62c99912023-05-11 11:06:53 +08001779static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001780{
1781 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1782 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1783 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1784 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1785 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1786 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1787 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1788 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1789 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1790 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1791 0x25, 0xB2, 0x07, 0x2F }
1792};
1793
1794static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001795{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001796#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001797
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001798#if defined(MBEDTLS_CIPHER_MODE_XTS)
1799/*
1800 * AES-XTS test vectors from:
1801 *
1802 * IEEE P1619/D16 Annex B
1803 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1804 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1805 */
1806static const unsigned char aes_test_xts_key[][32] =
1807{
1808 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1812 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1813 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1814 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1815 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1816 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1817 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1818 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1819 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1820};
1821
1822static const unsigned char aes_test_xts_pt32[][32] =
1823{
1824 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1825 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1828 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1829 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1830 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1831 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1832 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1833 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1834 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1835 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1836};
1837
1838static const unsigned char aes_test_xts_ct32[][32] =
1839{
1840 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1841 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1842 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1843 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1844 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1845 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1846 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1847 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1848 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1849 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1850 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1851 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1852};
1853
1854static const unsigned char aes_test_xts_data_unit[][16] =
1855{
Gilles Peskine449bd832023-01-11 14:50:10 +01001856 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1858 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1860 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1861 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001862};
1863
1864#endif /* MBEDTLS_CIPHER_MODE_XTS */
1865
Paul Bakker5121ce52009-01-03 21:22:43 +00001866/*
1867 * Checkup routine
1868 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001869int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001870{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001871 int ret = 0, i, j, u, mode;
1872 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001873 unsigned char key[32];
1874 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001875 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001876#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1877 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001879#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001881 unsigned char prv[16];
1882#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001883#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1884 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001885 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001886#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001887#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001888 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001889#endif
1890#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001891 unsigned char nonce_counter[16];
1892 unsigned char stream_block[16];
1893#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001894 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001895
Gilles Peskine449bd832023-01-11 14:50:10 +01001896 memset(key, 0, 32);
1897 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001898
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001899 if (verbose != 0) {
1900#if defined(MBEDTLS_AES_ALT)
1901 mbedtls_printf(" AES note: alternative implementation.\n");
1902#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001903#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001904#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001905 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001906#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001907 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001908#else
1909#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1910#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001911 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1912 mbedtls_printf(" AES note: using AESNI.\n");
1913 } else
1914#endif
Jerry Yu2319af02023-08-17 10:38:57 +08001915#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) && defined(__GNUC__)
1916 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1917 mbedtls_printf(" AES note: using VIA Padlock.\n");
1918 } else
1919#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001920#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1921 if (mbedtls_aesce_has_support()) {
1922 mbedtls_printf(" AES note: using AESCE.\n");
1923 } else
1924#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001925 {
1926#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1927 mbedtls_printf(" AES note: built-in implementation.\n");
1928#endif
1929 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001930#endif /* MBEDTLS_AES_ALT */
1931 }
1932
Paul Bakker5121ce52009-01-03 21:22:43 +00001933 /*
1934 * ECB mode
1935 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001936 {
1937 static const int num_tests =
1938 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001939
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001940 for (i = 0; i < num_tests << 1; i++) {
1941 u = i >> 1;
1942 keybits = 128 + u * 64;
1943 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001944
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001945 if (verbose != 0) {
1946 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1947 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1948 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001949
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001950 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001951
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001952 if (mode == MBEDTLS_AES_DECRYPT) {
1953 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1954 aes_tests = aes_test_ecb_dec[u];
1955 } else {
1956 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1957 aes_tests = aes_test_ecb_enc[u];
1958 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001959
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001960 /*
1961 * AES-192 is an optional feature that may be unavailable when
1962 * there is an alternative underlying implementation i.e. when
1963 * MBEDTLS_AES_ALT is defined.
1964 */
1965 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1966 mbedtls_printf("skipped\n");
1967 continue;
1968 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001969 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001970 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001971
1972 for (j = 0; j < 10000; j++) {
1973 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1974 if (ret != 0) {
1975 goto exit;
1976 }
1977 }
1978
1979 if (memcmp(buf, aes_tests, 16) != 0) {
1980 ret = 1;
1981 goto exit;
1982 }
1983
1984 if (verbose != 0) {
1985 mbedtls_printf("passed\n");
1986 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001987 }
1988
Gilles Peskine449bd832023-01-11 14:50:10 +01001989 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001990 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001991 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001992 }
1993
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001994#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001995 /*
1996 * CBC mode
1997 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001998 {
1999 static const int num_tests =
2000 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00002001
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002002 for (i = 0; i < num_tests << 1; i++) {
2003 u = i >> 1;
2004 keybits = 128 + u * 64;
2005 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01002006
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002007 if (verbose != 0) {
2008 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2009 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002010 }
2011
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002012 memset(iv, 0, 16);
2013 memset(prv, 0, 16);
2014 memset(buf, 0, 16);
2015
2016 if (mode == MBEDTLS_AES_DECRYPT) {
2017 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2018 aes_tests = aes_test_cbc_dec[u];
2019 } else {
2020 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2021 aes_tests = aes_test_cbc_enc[u];
2022 }
2023
2024 /*
2025 * AES-192 is an optional feature that may be unavailable when
2026 * there is an alternative underlying implementation i.e. when
2027 * MBEDTLS_AES_ALT is defined.
2028 */
2029 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2030 mbedtls_printf("skipped\n");
2031 continue;
2032 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002033 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002034 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002035
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002036 for (j = 0; j < 10000; j++) {
2037 if (mode == MBEDTLS_AES_ENCRYPT) {
2038 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002039
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002040 memcpy(tmp, prv, 16);
2041 memcpy(prv, buf, 16);
2042 memcpy(buf, tmp, 16);
2043 }
2044
2045 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2046 if (ret != 0) {
2047 goto exit;
2048 }
2049
2050 }
2051
2052 if (memcmp(buf, aes_tests, 16) != 0) {
2053 ret = 1;
2054 goto exit;
2055 }
2056
2057 if (verbose != 0) {
2058 mbedtls_printf("passed\n");
2059 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002060 }
2061
Gilles Peskine449bd832023-01-11 14:50:10 +01002062 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002063 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002064 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002065 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002066#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002068#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002069 /*
2070 * CFB128 mode
2071 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002072 {
2073 static const int num_tests =
2074 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002075
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002076 for (i = 0; i < num_tests << 1; i++) {
2077 u = i >> 1;
2078 keybits = 128 + u * 64;
2079 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002080
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002081 if (verbose != 0) {
2082 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2083 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2084 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002085
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002086 memcpy(iv, aes_test_cfb128_iv, 16);
2087 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002089 offset = 0;
2090 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2091 /*
2092 * AES-192 is an optional feature that may be unavailable when
2093 * there is an alternative underlying implementation i.e. when
2094 * MBEDTLS_AES_ALT is defined.
2095 */
2096 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2097 mbedtls_printf("skipped\n");
2098 continue;
2099 } else if (ret != 0) {
2100 goto exit;
2101 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002102
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002103 if (mode == MBEDTLS_AES_DECRYPT) {
2104 memcpy(buf, aes_test_cfb128_ct[u], 64);
2105 aes_tests = aes_test_cfb128_pt;
2106 } else {
2107 memcpy(buf, aes_test_cfb128_pt, 64);
2108 aes_tests = aes_test_cfb128_ct[u];
2109 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002110
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002111 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2112 if (ret != 0) {
2113 goto exit;
2114 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002115
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002116 if (memcmp(buf, aes_tests, 64) != 0) {
2117 ret = 1;
2118 goto exit;
2119 }
2120
2121 if (verbose != 0) {
2122 mbedtls_printf("passed\n");
2123 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002124 }
2125
Gilles Peskine449bd832023-01-11 14:50:10 +01002126 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002127 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002128 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002129 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002130#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002131
Simon Butcherad4e4932018-04-29 00:43:47 +01002132#if defined(MBEDTLS_CIPHER_MODE_OFB)
2133 /*
2134 * OFB mode
2135 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002136 {
2137 static const int num_tests =
2138 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002139
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002140 for (i = 0; i < num_tests << 1; i++) {
2141 u = i >> 1;
2142 keybits = 128 + u * 64;
2143 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002144
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002145 if (verbose != 0) {
2146 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2147 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2148 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002149
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002150 memcpy(iv, aes_test_ofb_iv, 16);
2151 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002152
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002153 offset = 0;
2154 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2155 /*
2156 * AES-192 is an optional feature that may be unavailable when
2157 * there is an alternative underlying implementation i.e. when
2158 * MBEDTLS_AES_ALT is defined.
2159 */
2160 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2161 mbedtls_printf("skipped\n");
2162 continue;
2163 } else if (ret != 0) {
2164 goto exit;
2165 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002166
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002167 if (mode == MBEDTLS_AES_DECRYPT) {
2168 memcpy(buf, aes_test_ofb_ct[u], 64);
2169 aes_tests = aes_test_ofb_pt;
2170 } else {
2171 memcpy(buf, aes_test_ofb_pt, 64);
2172 aes_tests = aes_test_ofb_ct[u];
2173 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002174
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002175 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2176 if (ret != 0) {
2177 goto exit;
2178 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002179
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002180 if (memcmp(buf, aes_tests, 64) != 0) {
2181 ret = 1;
2182 goto exit;
2183 }
2184
2185 if (verbose != 0) {
2186 mbedtls_printf("passed\n");
2187 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002188 }
2189
Gilles Peskine449bd832023-01-11 14:50:10 +01002190 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002191 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002192 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002193 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002194#endif /* MBEDTLS_CIPHER_MODE_OFB */
2195
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002196#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002197 /*
2198 * CTR mode
2199 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002200 {
2201 static const int num_tests =
2202 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002203
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002204 for (i = 0; i < num_tests << 1; i++) {
2205 u = i >> 1;
2206 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002207
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002208 if (verbose != 0) {
2209 mbedtls_printf(" AES-CTR-128 (%s): ",
2210 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2211 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002212
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002213 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2214 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002215
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002216 offset = 0;
2217 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2218 goto exit;
2219 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002220
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002221 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002222
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002223 if (mode == MBEDTLS_AES_DECRYPT) {
2224 memcpy(buf, aes_test_ctr_ct[u], len);
2225 aes_tests = aes_test_ctr_pt[u];
2226 } else {
2227 memcpy(buf, aes_test_ctr_pt[u], len);
2228 aes_tests = aes_test_ctr_ct[u];
2229 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002230
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002231 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2232 stream_block, buf, buf);
2233 if (ret != 0) {
2234 goto exit;
2235 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002236
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002237 if (memcmp(buf, aes_tests, len) != 0) {
2238 ret = 1;
2239 goto exit;
2240 }
2241
2242 if (verbose != 0) {
2243 mbedtls_printf("passed\n");
2244 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002245 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002246 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002247
Gilles Peskine449bd832023-01-11 14:50:10 +01002248 if (verbose != 0) {
2249 mbedtls_printf("\n");
2250 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002252
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002253#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002254 /*
2255 * XTS mode
2256 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002257 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002258 static const int num_tests =
2259 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2260 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002261
Gilles Peskine449bd832023-01-11 14:50:10 +01002262 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002263
Gilles Peskine449bd832023-01-11 14:50:10 +01002264 for (i = 0; i < num_tests << 1; i++) {
2265 const unsigned char *data_unit;
2266 u = i >> 1;
2267 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002268
Gilles Peskine449bd832023-01-11 14:50:10 +01002269 if (verbose != 0) {
2270 mbedtls_printf(" AES-XTS-128 (%s): ",
2271 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2272 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002273
Gilles Peskine449bd832023-01-11 14:50:10 +01002274 memset(key, 0, sizeof(key));
2275 memcpy(key, aes_test_xts_key[u], 32);
2276 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002277
Gilles Peskine449bd832023-01-11 14:50:10 +01002278 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002279
Gilles Peskine449bd832023-01-11 14:50:10 +01002280 if (mode == MBEDTLS_AES_DECRYPT) {
2281 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2282 if (ret != 0) {
2283 goto exit;
2284 }
2285 memcpy(buf, aes_test_xts_ct32[u], len);
2286 aes_tests = aes_test_xts_pt32[u];
2287 } else {
2288 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2289 if (ret != 0) {
2290 goto exit;
2291 }
2292 memcpy(buf, aes_test_xts_pt32[u], len);
2293 aes_tests = aes_test_xts_ct32[u];
2294 }
2295
2296
2297 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2298 buf, buf);
2299 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002300 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002301 }
2302
2303 if (memcmp(buf, aes_tests, len) != 0) {
2304 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002305 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002306 }
2307
2308 if (verbose != 0) {
2309 mbedtls_printf("passed\n");
2310 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002311 }
2312
Gilles Peskine449bd832023-01-11 14:50:10 +01002313 if (verbose != 0) {
2314 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002315 }
2316
Gilles Peskine449bd832023-01-11 14:50:10 +01002317 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002318 }
2319#endif /* MBEDTLS_CIPHER_MODE_XTS */
2320
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002321 ret = 0;
2322
2323exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002324 if (ret != 0 && verbose != 0) {
2325 mbedtls_printf("failed\n");
2326 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002327
Gilles Peskine449bd832023-01-11 14:50:10 +01002328 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002329
Gilles Peskine449bd832023-01-11 14:50:10 +01002330 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002331}
2332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002333#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002335#endif /* MBEDTLS_AES_C */