blob: 63b36c54c3a2e62c938e74115a746f984688983f [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__) || \
Jerry Yu372f7a02023-08-18 17:26:25 +080044 ((defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC))
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
Jerry Yu61fc5ed2023-08-18 17:28:48 +080055#if defined(MBEDTLS_PADLOCK_C)
56#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080057#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
58#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080059#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
60#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
61 "MBEDTLS_PADLOCK_C is set"
62#endif
63#endif
Jerry Yu02b15192023-04-23 14:43:19 +080064#endif
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000067#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000068#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020069#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000070#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010071#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080072#if defined(MBEDTLS_AESCE_C)
73#include "aesce.h"
74#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000075
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000076#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020079
Jerry Yu9e628622023-08-17 11:20:09 +080080#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000081static int aes_padlock_ace = -1;
82#endif
83
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000085/*
86 * Forward S-box
87 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010088#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
89 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000090static const unsigned char FSb[256] =
91{
92 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
93 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
94 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
95 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
96 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
97 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
98 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
99 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
100 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
101 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
102 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
103 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
104 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
105 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
106 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
107 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
108 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
109 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
110 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
111 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
112 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
113 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
114 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
115 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
116 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
117 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
118 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
119 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
120 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
121 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
122 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
123 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
124};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100125#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
126 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000127
128/*
129 * Forward tables
130 */
131#define FT \
132\
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
134 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
135 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
136 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
137 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
138 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
139 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
140 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
141 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
142 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
143 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
144 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
145 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
146 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
147 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
148 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
149 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
150 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
151 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
152 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
153 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
154 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
155 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
156 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
157 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
158 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
159 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
160 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
161 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
162 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
163 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
164 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
165 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
166 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
167 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
168 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
169 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
170 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
171 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
172 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
173 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
174 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
175 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
176 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
177 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
178 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
179 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
180 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
181 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
182 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
183 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
184 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
185 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
186 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
187 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
188 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
189 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
190 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
191 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
192 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
193 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
194 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
195 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
196 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 +0000197
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100198#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100199#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000201#undef V
202
Hanno Beckerad049a92017-06-19 16:31:54 +0100203#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000206static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000207#undef V
208
Gilles Peskine449bd832023-01-11 14:50:10 +0100209#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000210static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000211#undef V
212
Gilles Peskine449bd832023-01-11 14:50:10 +0100213#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000215#undef V
216
Hanno Becker177d3cf2017-06-07 15:52:48 +0100217#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200218
Dave Rodgman1be24632023-06-29 12:01:24 +0100219#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
220
Paul Bakker5121ce52009-01-03 21:22:43 +0000221#undef FT
222
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100223#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000224/*
225 * Reverse S-box
226 */
227static const unsigned char RSb[256] =
228{
229 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
230 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
231 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
232 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
233 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
234 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
235 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
236 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
237 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
238 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
239 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
240 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
241 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
242 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
243 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
244 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
245 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
246 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
247 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
248 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
249 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
250 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
251 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
252 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
253 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
254 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
255 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
256 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
257 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
258 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
259 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
260 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
261};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100262#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264/*
265 * Reverse tables
266 */
267#define RT \
268\
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
270 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
271 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
272 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
273 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
274 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
275 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
276 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
277 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
278 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
279 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
280 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
281 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
282 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
283 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
284 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
285 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
286 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
287 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
288 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
289 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
290 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
291 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
292 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
293 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
294 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
295 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
296 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
297 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
298 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
299 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
300 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
301 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
302 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
303 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
304 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
305 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
306 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
307 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
308 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
309 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
310 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
311 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
312 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
313 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
314 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
315 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
316 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
317 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
318 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
319 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
320 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
321 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
322 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
323 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
324 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
325 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
326 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
327 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
328 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
329 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
330 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
331 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
332 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 +0000333
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100334#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000338#undef V
339
Hanno Beckerad049a92017-06-19 16:31:54 +0100340#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200341
Gilles Peskine449bd832023-01-11 14:50:10 +0100342#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000343static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000344#undef V
345
Gilles Peskine449bd832023-01-11 14:50:10 +0100346#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000348#undef V
349
Gilles Peskine449bd832023-01-11 14:50:10 +0100350#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000352#undef V
353
Hanno Becker177d3cf2017-06-07 15:52:48 +0100354#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200355
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800356#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
357
Paul Bakker5121ce52009-01-03 21:22:43 +0000358#undef RT
359
Dave Rodgman34152a42023-06-27 18:31:24 +0100360#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000361/*
362 * Round constants
363 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000364static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000365{
366 0x00000001, 0x00000002, 0x00000004, 0x00000008,
367 0x00000010, 0x00000020, 0x00000040, 0x00000080,
368 0x0000001B, 0x00000036
369};
Dave Rodgman34152a42023-06-27 18:31:24 +0100370#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
374/*
375 * Forward S-box & tables
376 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100377#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
378 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000379static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100380#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
381 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100382#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200383static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100384#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200385static uint32_t FT1[256];
386static uint32_t FT2[256];
387static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100388#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100389#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
391/*
392 * Reverse S-box & tables
393 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100394#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000395static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100396#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100397
398#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000399static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100400#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000401static uint32_t RT1[256];
402static uint32_t RT2[256];
403static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100404#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100405#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
Dave Rodgman8c753f92023-06-27 18:16:13 +0100407#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000408/*
409 * Round constants
410 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000411static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
413/*
414 * Tables generation code
415 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100416#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
417#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
418#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420static int aes_init_done = 0;
421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000423{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800424 int i;
425 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800426 uint8_t pow[256];
427 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
429 /*
430 * compute pow and log tables over GF(2^8)
431 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000433 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800434 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800435 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 }
437
438 /*
439 * calculate the round constants
440 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800442 RCON[i] = x;
443 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 }
445
446 /*
447 * generate the forward and reverse S-boxes
448 */
449 FSb[0x00] = 0x63;
450 RSb[0x63] = 0x00;
451
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000453 x = pow[255 - log[i]];
454
Yanray Wangfe944ce2023-06-26 18:16:01 +0800455 y = x; y = (y << 1) | (y >> 7);
456 x ^= y; y = (y << 1) | (y >> 7);
457 x ^= y; y = (y << 1) | (y >> 7);
458 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000459 x ^= y ^ 0x63;
460
Yanray Wangfe944ce2023-06-26 18:16:01 +0800461 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000462 RSb[x] = (unsigned char) i;
463 }
464
465 /*
466 * generate the forward and reverse tables
467 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000469 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800470 y = XTIME(x);
471 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 FT0[i] = ((uint32_t) y) ^
474 ((uint32_t) x << 8) ^
475 ((uint32_t) x << 16) ^
476 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
Hanno Beckerad049a92017-06-19 16:31:54 +0100478#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 FT1[i] = ROTL8(FT0[i]);
480 FT2[i] = ROTL8(FT1[i]);
481 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100482#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
484 x = RSb[i];
485
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100486#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100487 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
488 ((uint32_t) MUL(0x09, x) << 8) ^
489 ((uint32_t) MUL(0x0D, x) << 16) ^
490 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
Hanno Beckerad049a92017-06-19 16:31:54 +0100492#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 RT1[i] = ROTL8(RT0[i]);
494 RT2[i] = ROTL8(RT1[i]);
495 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100496#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100497#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000498 }
499}
500
Dave Rodgman8c753f92023-06-27 18:16:13 +0100501#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
502
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200503#undef ROTL8
504
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
Hanno Beckerad049a92017-06-19 16:31:54 +0100507#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200508
Gilles Peskine449bd832023-01-11 14:50:10 +0100509#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
510#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
511#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200512
513#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100514#define AES_RT1(idx) ROTL8(RT0[idx])
515#define AES_RT2(idx) ROTL16(RT0[idx])
516#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200517
518#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100519#define AES_FT1(idx) ROTL8(FT0[idx])
520#define AES_FT2(idx) ROTL16(FT0[idx])
521#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200522
Hanno Becker177d3cf2017-06-07 15:52:48 +0100523#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200524
525#define AES_RT0(idx) RT0[idx]
526#define AES_RT1(idx) RT1[idx]
527#define AES_RT2(idx) RT2[idx]
528#define AES_RT3(idx) RT3[idx]
529
530#define AES_FT0(idx) FT0[idx]
531#define AES_FT1(idx) FT1[idx]
532#define AES_FT2(idx) FT2[idx]
533#define AES_FT3(idx) FT3[idx]
534
Hanno Becker177d3cf2017-06-07 15:52:48 +0100535#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200538{
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200540}
541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200543{
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200545 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200547
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200549}
550
Jaeden Amero9366feb2018-05-29 18:55:17 +0100551#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100552void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100553{
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 mbedtls_aes_init(&ctx->crypt);
555 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100556}
557
Gilles Peskine449bd832023-01-11 14:50:10 +0100558void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100559{
Gilles Peskine449bd832023-01-11 14:50:10 +0100560 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100561 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 }
Simon Butcher5201e412018-12-06 17:40:14 +0000563
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 mbedtls_aes_free(&ctx->crypt);
565 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100566}
567#endif /* MBEDTLS_CIPHER_MODE_XTS */
568
Gilles Peskine0de8f852023-03-16 17:14:59 +0100569/* Some implementations need the round keys to be aligned.
570 * Return an offset to be added to buf, such that (buf + offset) is
571 * correctly aligned.
572 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
573 * i.e. an offset of 1 means 4 bytes and so on.
574 */
Jerry Yu96084472023-08-17 18:10:45 +0800575#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100576 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100577#define MAY_NEED_TO_ALIGN
578#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100579
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100580#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
581 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100582static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
583{
584#if defined(MAY_NEED_TO_ALIGN)
585 int align_16_bytes = 0;
586
Jerry Yu9e628622023-08-17 11:20:09 +0800587#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100588 if (aes_padlock_ace == -1) {
589 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
590 }
591 if (aes_padlock_ace) {
592 align_16_bytes = 1;
593 }
594#endif
595
Gilles Peskine9c682e72023-03-16 17:21:33 +0100596#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100597 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
598 align_16_bytes = 1;
599 }
600#endif
601
602 if (align_16_bytes) {
603 /* These implementations needs 16-byte alignment
604 * for the round key array. */
605 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
606 if (delta == 0) {
607 return 0;
608 } else {
609 return 4 - delta; // 16 bytes = 4 uint32_t
610 }
611 }
612#else /* MAY_NEED_TO_ALIGN */
613 (void) buf;
614#endif /* MAY_NEED_TO_ALIGN */
615
616 return 0;
617}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100618#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
619 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100620
Paul Bakker5121ce52009-01-03 21:22:43 +0000621/*
622 * AES key schedule (encryption)
623 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200624#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100625int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
626 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000627{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000628 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Gilles Peskine449bd832023-01-11 14:50:10 +0100630 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800632#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 case 192: ctx->nr = 12; break;
634 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800635#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 }
638
Simon Butcher5201e412018-12-06 17:40:14 +0000639#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000641 aes_gen_tables();
642 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000643 }
644#endif
645
Gilles Peskine0de8f852023-03-16 17:14:59 +0100646 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100647 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000648
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100649#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
651 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
652 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100653#endif
654
Jerry Yu3f2fb712023-01-10 17:05:42 +0800655#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
656 if (mbedtls_aesce_has_support()) {
657 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
658 }
659#endif
660
Jerry Yu29c91ba2023-08-04 11:02:04 +0800661#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800662 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 }
665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 case 10:
668
Jerry Yu3a0f0442023-08-17 17:06:21 +0800669 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
672 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
673 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
674 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
676 RK[5] = RK[1] ^ RK[4];
677 RK[6] = RK[2] ^ RK[5];
678 RK[7] = RK[3] ^ RK[6];
679 }
680 break;
681
Arto Kinnunen732ca322023-04-14 14:26:10 +0800682#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 case 12:
684
Jerry Yu3a0f0442023-08-17 17:06:21 +0800685 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000686 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100687 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
688 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
689 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
690 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
692 RK[7] = RK[1] ^ RK[6];
693 RK[8] = RK[2] ^ RK[7];
694 RK[9] = RK[3] ^ RK[8];
695 RK[10] = RK[4] ^ RK[9];
696 RK[11] = RK[5] ^ RK[10];
697 }
698 break;
699
700 case 14:
701
Jerry Yu3a0f0442023-08-17 17:06:21 +0800702 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
705 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
706 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
707 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
709 RK[9] = RK[1] ^ RK[8];
710 RK[10] = RK[2] ^ RK[9];
711 RK[11] = RK[3] ^ RK[10];
712
713 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
715 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
716 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
717 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000718
719 RK[13] = RK[5] ^ RK[12];
720 RK[14] = RK[6] ^ RK[13];
721 RK[15] = RK[7] ^ RK[14];
722 }
723 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800724#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000725 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800728#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000729}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200730#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
732/*
733 * AES key schedule (decryption)
734 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200735#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100736int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
737 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000738{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800739#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800740 uint32_t *SK;
741#endif
742 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000744 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800745
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Gilles Peskine0de8f852023-03-16 17:14:59 +0100749 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100750 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000751
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200752 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200754 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000756
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200757 ctx->nr = cty.nr;
758
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100759#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
761 mbedtls_aesni_inverse_key((unsigned char *) RK,
762 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200763 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100764 }
765#endif
766
Jerry Yue096da12023-01-10 17:07:01 +0800767#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
768 if (mbedtls_aesce_has_support()) {
769 mbedtls_aesce_inverse_key(
770 (unsigned char *) RK,
771 (const unsigned char *) (cty.buf + cty.rk_offset),
772 ctx->nr);
773 goto exit;
774 }
775#endif
776
Jerry Yu29c91ba2023-08-04 11:02:04 +0800777#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100778 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
780 *RK++ = *SK++;
781 *RK++ = *SK++;
782 *RK++ = *SK++;
783 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800784 SK -= 8;
785 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
786 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
788 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
789 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
790 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000791 }
792 }
793
794 *RK++ = *SK++;
795 *RK++ = *SK++;
796 *RK++ = *SK++;
797 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800798#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200799exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000803}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100804#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100805
806#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100807static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
808 unsigned int keybits,
809 const unsigned char **key1,
810 unsigned int *key1bits,
811 const unsigned char **key2,
812 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100813{
814 const unsigned int half_keybits = keybits / 2;
815 const unsigned int half_keybytes = half_keybits / 8;
816
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818 case 256: break;
819 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100821 }
822
823 *key1bits = half_keybits;
824 *key2bits = half_keybits;
825 *key1 = &key[0];
826 *key2 = &key[half_keybytes];
827
828 return 0;
829}
830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
832 const unsigned char *key,
833 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100834{
Janos Follath24eed8d2019-11-22 13:21:35 +0000835 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100836 const unsigned char *key1, *key2;
837 unsigned int key1bits, key2bits;
838
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
840 &key2, &key2bits);
841 if (ret != 0) {
842 return ret;
843 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100844
845 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
847 if (ret != 0) {
848 return ret;
849 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100850
851 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100853}
854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
856 const unsigned char *key,
857 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100858{
Janos Follath24eed8d2019-11-22 13:21:35 +0000859 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100860 const unsigned char *key1, *key2;
861 unsigned int key1bits, key2bits;
862
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
864 &key2, &key2bits);
865 if (ret != 0) {
866 return ret;
867 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100868
869 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
871 if (ret != 0) {
872 return ret;
873 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100874
875 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100877}
878#endif /* MBEDTLS_CIPHER_MODE_XTS */
879
Gilles Peskine449bd832023-01-11 14:50:10 +0100880#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100881 do \
882 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100883 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
884 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
885 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
886 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100887 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
889 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
890 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
891 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100892 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
894 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
895 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
896 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100897 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
899 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
900 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
901 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
902 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100905 do \
906 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
908 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
909 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
910 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100911 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
913 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
914 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
915 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100916 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
918 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
919 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
920 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100921 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
923 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
924 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
925 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
926 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000927
928/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200929 * AES-ECB block encryption
930 */
931#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100932int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
933 const unsigned char input[16],
934 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935{
936 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100937 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200939 uint32_t X[4];
940 uint32_t Y[4];
941 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
944 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
945 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
946 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
949 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]);
950 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 +0200951 }
952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 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 +0200954
Gilles Peskine5197c662020-08-26 17:03:24 +0200955 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
957 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
958 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
959 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200960
Gilles Peskine5197c662020-08-26 17:03:24 +0200961 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
965 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200966
Gilles Peskine5197c662020-08-26 17:03:24 +0200967 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
971 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200972
Gilles Peskine5197c662020-08-26 17:03:24 +0200973 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
975 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
977 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
980 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
981 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
982 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000983
Gilles Peskine449bd832023-01-11 14:50:10 +0100984 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500985
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200987}
988#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
989
990/*
991 * AES-ECB block decryption
992 */
993#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100994int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
995 const unsigned char input[16],
996 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200997{
998 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100999 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001001 uint32_t X[4];
1002 uint32_t Y[4];
1003 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1006 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1007 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1008 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1011 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]);
1012 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 +02001013 }
1014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 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 +02001016
Gilles Peskine5197c662020-08-26 17:03:24 +02001017 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1019 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1020 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1021 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001022
Gilles Peskine5197c662020-08-26 17:03:24 +02001023 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1027 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001028
Gilles Peskine5197c662020-08-26 17:03:24 +02001029 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1033 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001034
Gilles Peskine5197c662020-08-26 17:03:24 +02001035 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1037 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1039 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001040
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1042 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1043 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1044 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001049}
1050#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1051
Gilles Peskine0de8f852023-03-16 17:14:59 +01001052#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001053/* VIA Padlock and our intrinsics-based implementation of AESNI require
1054 * the round keys to be aligned on a 16-byte boundary. We take care of this
1055 * before creating them, but the AES context may have moved (this can happen
1056 * if the library is called from a language with managed memory), and in later
1057 * calls it might have a different alignment with respect to 16-byte memory.
1058 * So we may need to realign.
1059 */
1060static void aes_maybe_realign(mbedtls_aes_context *ctx)
1061{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001062 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1063 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001064 memmove(ctx->buf + new_offset, // new address
1065 ctx->buf + ctx->rk_offset, // current address
1066 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1067 ctx->rk_offset = new_offset;
1068 }
1069}
1070#endif
1071
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001072/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001073 * AES-ECB block encryption/decryption
1074 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001075int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1076 int mode,
1077 const unsigned char input[16],
1078 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001079{
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001081 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001083
Gilles Peskine0de8f852023-03-16 17:14:59 +01001084#if defined(MAY_NEED_TO_ALIGN)
1085 aes_maybe_realign(ctx);
1086#endif
1087
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001088#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1090 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1091 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001092#endif
1093
Jerry Yu2bb3d812023-01-10 17:38:26 +08001094#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1095 if (mbedtls_aesce_has_support()) {
1096 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1097 }
1098#endif
1099
Jerry Yu9e628622023-08-17 11:20:09 +08001100#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001102 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001103 }
1104#endif
1105
Jerry Yu29c91ba2023-08-04 11:02:04 +08001106#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 if (mode == MBEDTLS_AES_ENCRYPT) {
1108 return mbedtls_internal_aes_encrypt(ctx, input, output);
1109 } else {
1110 return mbedtls_internal_aes_decrypt(ctx, input, output);
1111 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001112#endif
1113
Paul Bakker5121ce52009-01-03 21:22:43 +00001114}
1115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001116#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001117
Paul Bakker5121ce52009-01-03 21:22:43 +00001118/*
1119 * AES-CBC buffer encryption/decryption
1120 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001121int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1122 int mode,
1123 size_t length,
1124 unsigned char iv[16],
1125 const unsigned char *input,
1126 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001127{
Gilles Peskine7820a572021-07-07 21:08:28 +02001128 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001129 unsigned char temp[16];
1130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001132 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001134
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 if (length % 16) {
1136 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1137 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001138
Jerry Yu9e628622023-08-17 11:20:09 +08001139#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 if (aes_padlock_ace > 0) {
1141 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1142 return 0;
1143 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001144
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001145 // If padlock data misaligned, we just fall back to
1146 // unaccelerated mode
1147 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 }
1149#endif
1150
Dave Rodgman906c63c2023-06-14 17:53:51 +01001151 const unsigned char *ivp = iv;
1152
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 if (mode == MBEDTLS_AES_DECRYPT) {
1154 while (length > 0) {
1155 memcpy(temp, input, 16);
1156 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1157 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001158 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001160 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001161 * the result for the next block in CBC, and the cost of transferring that data from
1162 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001163 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001164
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001166
1167 input += 16;
1168 output += 16;
1169 length -= 16;
1170 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 } else {
1172 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001173 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001174
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1176 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001177 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001179 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001180
1181 input += 16;
1182 output += 16;
1183 length -= 16;
1184 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001185 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001186 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001187 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001188
Gilles Peskine7820a572021-07-07 21:08:28 +02001189exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001191}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001192#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001193
Aorimn5f778012016-06-09 23:22:58 +02001194#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001195
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001196typedef unsigned char mbedtls_be128[16];
1197
1198/*
1199 * GF(2^128) multiplication function
1200 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001201 * This function multiplies a field element by x in the polynomial field
1202 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001203 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001204 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001205 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001206#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001207MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001208#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001209static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001210 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001211{
1212 uint64_t a, b, ra, rb;
1213
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 a = MBEDTLS_GET_UINT64_LE(x, 0);
1215 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001216
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1218 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001219
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1221 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001222}
1223
Aorimn5f778012016-06-09 23:22:58 +02001224/*
1225 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001226 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001227 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001228 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001229 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001230#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001231MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001232#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001233int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1234 int mode,
1235 size_t length,
1236 const unsigned char data_unit[16],
1237 const unsigned char *input,
1238 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001239{
Janos Follath24eed8d2019-11-22 13:21:35 +00001240 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241 size_t blocks = length / 16;
1242 size_t leftover = length % 16;
1243 unsigned char tweak[16];
1244 unsigned char prev_tweak[16];
1245 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001246
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001248 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001250
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001251 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 }
Aorimn5f778012016-06-09 23:22:58 +02001255
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001256 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001258 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 }
Aorimn5f778012016-06-09 23:22:58 +02001260
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1263 data_unit, tweak);
1264 if (ret != 0) {
1265 return ret;
1266 }
Aorimn5f778012016-06-09 23:22:58 +02001267
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001269 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001270 /* We are on the last block in a decrypt operation that has
1271 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001272 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 * the leftovers and then update the current tweak for use on this,
1274 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 memcpy(prev_tweak, tweak, sizeof(tweak));
1276 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001277 }
1278
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001280
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1282 if (ret != 0) {
1283 return ret;
1284 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001287
1288 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001290
1291 output += 16;
1292 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001293 }
1294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001296 /* If we are on the leftover bytes in a decrypt operation, we need to
1297 * use the previous tweak for these bytes (as saved in prev_tweak). */
1298 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001299
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300 /* We are now on the final part of the data unit, which doesn't divide
1301 * evenly by 16. It's time for ciphertext stealing. */
1302 size_t i;
1303 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001304
Jaeden Amerod82cd862018-04-28 15:02:45 +01001305 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001306 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001308 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001309 }
Aorimn5f778012016-06-09 23:22:58 +02001310
Dave Rodgman069e7f42022-11-24 19:37:26 +00001311 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001313
Jaeden Amerod82cd862018-04-28 15:02:45 +01001314 /* Copy ciphertext bytes from the previous block for input in this
1315 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001317
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1319 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001320 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001321 }
Aorimn5f778012016-06-09 23:22:58 +02001322
Jaeden Amerod82cd862018-04-28 15:02:45 +01001323 /* Write the result back to the previous block, overriding the previous
1324 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001326 }
1327
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001329}
1330#endif /* MBEDTLS_CIPHER_MODE_XTS */
1331
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001332#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001333/*
1334 * AES-CFB128 buffer encryption/decryption
1335 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001336int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1337 int mode,
1338 size_t length,
1339 size_t *iv_off,
1340 unsigned char iv[16],
1341 const unsigned char *input,
1342 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001343{
Paul Bakker27fdf462011-06-09 13:55:13 +00001344 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001345 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001346 size_t n;
1347
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001349 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001351
1352 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001353
Gilles Peskine449bd832023-01-11 14:50:10 +01001354 if (n > 15) {
1355 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1356 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001357
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 if (mode == MBEDTLS_AES_DECRYPT) {
1359 while (length--) {
1360 if (n == 0) {
1361 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1362 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001363 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001365 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001366
1367 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001369 iv[n] = (unsigned char) c;
1370
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001372 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 } else {
1374 while (length--) {
1375 if (n == 0) {
1376 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1377 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001378 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001380 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001381
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001383
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001385 }
1386 }
1387
1388 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001389 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001390
Gilles Peskine7820a572021-07-07 21:08:28 +02001391exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001393}
Paul Bakker556efba2014-01-24 15:38:12 +01001394
1395/*
1396 * AES-CFB8 buffer encryption/decryption
1397 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001398int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1399 int mode,
1400 size_t length,
1401 unsigned char iv[16],
1402 const unsigned char *input,
1403 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001404{
Gilles Peskine7820a572021-07-07 21:08:28 +02001405 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001406 unsigned char c;
1407 unsigned char ov[17];
1408
Gilles Peskine449bd832023-01-11 14:50:10 +01001409 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001410 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001411 }
1412 while (length--) {
1413 memcpy(ov, iv, 16);
1414 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1415 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001416 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001417 }
Paul Bakker556efba2014-01-24 15:38:12 +01001418
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001420 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 }
Paul Bakker556efba2014-01-24 15:38:12 +01001422
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001424
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001426 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001427 }
Paul Bakker556efba2014-01-24 15:38:12 +01001428
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001430 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001431 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001432
Gilles Peskine7820a572021-07-07 21:08:28 +02001433exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001434 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001435}
Simon Butcher76a5b222018-04-22 22:57:27 +01001436#endif /* MBEDTLS_CIPHER_MODE_CFB */
1437
1438#if defined(MBEDTLS_CIPHER_MODE_OFB)
1439/*
1440 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1441 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001442int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1443 size_t length,
1444 size_t *iv_off,
1445 unsigned char iv[16],
1446 const unsigned char *input,
1447 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001448{
Simon Butcherad4e4932018-04-29 00:43:47 +01001449 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001450 size_t n;
1451
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001452 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001453
Gilles Peskine449bd832023-01-11 14:50:10 +01001454 if (n > 15) {
1455 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1456 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001457
Gilles Peskine449bd832023-01-11 14:50:10 +01001458 while (length--) {
1459 if (n == 0) {
1460 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1461 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001462 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001463 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001464 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001465 *output++ = *input++ ^ iv[n];
1466
Gilles Peskine449bd832023-01-11 14:50:10 +01001467 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001468 }
1469
1470 *iv_off = n;
1471
Simon Butcherad4e4932018-04-29 00:43:47 +01001472exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001473 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001474}
1475#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001477#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001478/*
1479 * AES-CTR buffer encryption/decryption
1480 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001481int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1482 size_t length,
1483 size_t *nc_off,
1484 unsigned char nonce_counter[16],
1485 unsigned char stream_block[16],
1486 const unsigned char *input,
1487 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001488{
Paul Bakker369e14b2012-04-18 14:16:09 +00001489 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001490 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001491 size_t n;
1492
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001493 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001494
Gilles Peskine449bd832023-01-11 14:50:10 +01001495 if (n > 0x0F) {
1496 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1497 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001498
Gilles Peskine449bd832023-01-11 14:50:10 +01001499 while (length--) {
1500 if (n == 0) {
1501 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1502 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001503 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001504 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001505
Gilles Peskine449bd832023-01-11 14:50:10 +01001506 for (i = 16; i > 0; i--) {
1507 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001508 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001509 }
1510 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001511 }
1512 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001513 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001514
Gilles Peskine449bd832023-01-11 14:50:10 +01001515 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001516 }
1517
1518 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001519 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001520
Gilles Peskine7820a572021-07-07 21:08:28 +02001521exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001522 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001523}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001528#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001529/*
1530 * AES test vectors from:
1531 *
1532 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1533 */
Yanray Wang62c99912023-05-11 11:06:53 +08001534static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001535{
1536 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1537 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001538#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001539 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1540 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1541 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1542 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001543#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001544};
1545
Yanray Wang62c99912023-05-11 11:06:53 +08001546static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001547{
1548 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1549 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
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 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1552 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1553 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1554 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001555#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001556};
1557
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001558#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001559static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001560{
1561 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1562 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001563#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001564 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1565 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1566 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1567 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001568#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001569};
1570
Yanray Wang62c99912023-05-11 11:06:53 +08001571static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001572{
1573 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1574 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
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 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1577 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1578 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1579 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001580#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001581};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001582#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001583
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001584#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001585/*
1586 * AES-CFB128 test vectors from:
1587 *
1588 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1589 */
Yanray Wang62c99912023-05-11 11:06:53 +08001590static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001591{
1592 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1593 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001594#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001595 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1596 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1597 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1598 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1599 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1600 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1601 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001602#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001603};
1604
1605static const unsigned char aes_test_cfb128_iv[16] =
1606{
1607 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1608 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1609};
1610
1611static const unsigned char aes_test_cfb128_pt[64] =
1612{
1613 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1614 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1615 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1616 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1617 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1618 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1619 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1620 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1621};
1622
Yanray Wang62c99912023-05-11 11:06:53 +08001623static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001624{
1625 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1626 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1627 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1628 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1629 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1630 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1631 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1632 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001633#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001634 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1635 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1636 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1637 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1638 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1639 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1640 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1641 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1642 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1643 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1644 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1645 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1646 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1647 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1648 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1649 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001650#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001651};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001652#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001653
Simon Butcherad4e4932018-04-29 00:43:47 +01001654#if defined(MBEDTLS_CIPHER_MODE_OFB)
1655/*
1656 * AES-OFB test vectors from:
1657 *
Simon Butcher5db13622018-06-04 22:11:25 +01001658 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001659 */
Yanray Wang62c99912023-05-11 11:06:53 +08001660static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001661{
1662 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1663 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001664#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001665 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1666 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1667 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1668 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1669 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1670 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1671 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001672#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001673};
1674
1675static const unsigned char aes_test_ofb_iv[16] =
1676{
1677 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1678 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1679};
1680
1681static const unsigned char aes_test_ofb_pt[64] =
1682{
1683 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1684 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1685 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1686 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1687 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1688 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1689 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1690 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1691};
1692
Yanray Wang62c99912023-05-11 11:06:53 +08001693static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001694{
1695 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1696 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1697 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1698 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1699 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1700 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1701 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1702 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001703#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001704 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1705 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1706 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1707 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1708 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1709 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1710 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1711 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1712 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1713 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1714 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1715 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1716 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1717 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1718 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1719 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001720#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001721};
1722#endif /* MBEDTLS_CIPHER_MODE_OFB */
1723
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001724#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001725/*
1726 * AES-CTR test vectors from:
1727 *
1728 * http://www.faqs.org/rfcs/rfc3686.html
1729 */
1730
Yanray Wang62c99912023-05-11 11:06:53 +08001731static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001732{
1733 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1734 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1735 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1736 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1737 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1738 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1739};
1740
Yanray Wang62c99912023-05-11 11:06:53 +08001741static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001742{
1743 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1744 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1745 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1746 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1747 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1748 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1749};
1750
Yanray Wang62c99912023-05-11 11:06:53 +08001751static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001752{
1753 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1754 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001755 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1756 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1757 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1758 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1759
1760 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1761 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1762 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1763 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1764 0x20, 0x21, 0x22, 0x23 }
1765};
1766
Yanray Wang62c99912023-05-11 11:06:53 +08001767static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001768{
1769 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1770 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1771 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1772 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1773 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1774 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1775 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1776 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1777 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1778 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1779 0x25, 0xB2, 0x07, 0x2F }
1780};
1781
1782static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001783{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001784#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001785
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001786#if defined(MBEDTLS_CIPHER_MODE_XTS)
1787/*
1788 * AES-XTS test vectors from:
1789 *
1790 * IEEE P1619/D16 Annex B
1791 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1792 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1793 */
1794static const unsigned char aes_test_xts_key[][32] =
1795{
1796 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1800 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1801 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1802 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1803 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1804 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1805 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1806 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1807 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1808};
1809
1810static const unsigned char aes_test_xts_pt32[][32] =
1811{
1812 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1816 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1817 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1818 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1819 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1820 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1821 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1822 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1823 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1824};
1825
1826static const unsigned char aes_test_xts_ct32[][32] =
1827{
1828 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1829 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1830 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1831 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1832 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1833 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1834 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1835 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1836 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1837 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1838 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1839 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1840};
1841
1842static const unsigned char aes_test_xts_data_unit[][16] =
1843{
Gilles Peskine449bd832023-01-11 14:50:10 +01001844 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1846 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1848 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001850};
1851
1852#endif /* MBEDTLS_CIPHER_MODE_XTS */
1853
Paul Bakker5121ce52009-01-03 21:22:43 +00001854/*
1855 * Checkup routine
1856 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001857int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001858{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001859 int ret = 0, i, j, u, mode;
1860 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001861 unsigned char key[32];
1862 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001863 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001864#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1865 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001866 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001867#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001868#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001869 unsigned char prv[16];
1870#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001871#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1872 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001873 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001874#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001875#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001876 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001877#endif
1878#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001879 unsigned char nonce_counter[16];
1880 unsigned char stream_block[16];
1881#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001882 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001883
Gilles Peskine449bd832023-01-11 14:50:10 +01001884 memset(key, 0, 32);
1885 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001886
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001887 if (verbose != 0) {
1888#if defined(MBEDTLS_AES_ALT)
1889 mbedtls_printf(" AES note: alternative implementation.\n");
1890#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001891#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001892#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001893 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001894#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001895 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001896#else
1897#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1898#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001899 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1900 mbedtls_printf(" AES note: using AESNI.\n");
1901 } else
1902#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001903#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001904 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1905 mbedtls_printf(" AES note: using VIA Padlock.\n");
1906 } else
1907#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001908#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1909 if (mbedtls_aesce_has_support()) {
1910 mbedtls_printf(" AES note: using AESCE.\n");
1911 } else
1912#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001913 {
1914#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1915 mbedtls_printf(" AES note: built-in implementation.\n");
1916#endif
1917 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001918#endif /* MBEDTLS_AES_ALT */
1919 }
1920
Paul Bakker5121ce52009-01-03 21:22:43 +00001921 /*
1922 * ECB mode
1923 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001924 {
1925 static const int num_tests =
1926 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001927
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001928 for (i = 0; i < num_tests << 1; i++) {
1929 u = i >> 1;
1930 keybits = 128 + u * 64;
1931 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001932
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001933 if (verbose != 0) {
1934 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1935 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1936 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001937
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001938 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001939
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001940 if (mode == MBEDTLS_AES_DECRYPT) {
1941 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1942 aes_tests = aes_test_ecb_dec[u];
1943 } else {
1944 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1945 aes_tests = aes_test_ecb_enc[u];
1946 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001947
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001948 /*
1949 * AES-192 is an optional feature that may be unavailable when
1950 * there is an alternative underlying implementation i.e. when
1951 * MBEDTLS_AES_ALT is defined.
1952 */
1953 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1954 mbedtls_printf("skipped\n");
1955 continue;
1956 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001957 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001958 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001959
1960 for (j = 0; j < 10000; j++) {
1961 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1962 if (ret != 0) {
1963 goto exit;
1964 }
1965 }
1966
1967 if (memcmp(buf, aes_tests, 16) != 0) {
1968 ret = 1;
1969 goto exit;
1970 }
1971
1972 if (verbose != 0) {
1973 mbedtls_printf("passed\n");
1974 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001975 }
1976
Gilles Peskine449bd832023-01-11 14:50:10 +01001977 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001978 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001979 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001980 }
1981
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001982#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001983 /*
1984 * CBC mode
1985 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001986 {
1987 static const int num_tests =
1988 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001989
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001990 for (i = 0; i < num_tests << 1; i++) {
1991 u = i >> 1;
1992 keybits = 128 + u * 64;
1993 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001994
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001995 if (verbose != 0) {
1996 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1997 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001998 }
1999
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002000 memset(iv, 0, 16);
2001 memset(prv, 0, 16);
2002 memset(buf, 0, 16);
2003
2004 if (mode == MBEDTLS_AES_DECRYPT) {
2005 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2006 aes_tests = aes_test_cbc_dec[u];
2007 } else {
2008 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2009 aes_tests = aes_test_cbc_enc[u];
2010 }
2011
2012 /*
2013 * AES-192 is an optional feature that may be unavailable when
2014 * there is an alternative underlying implementation i.e. when
2015 * MBEDTLS_AES_ALT is defined.
2016 */
2017 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2018 mbedtls_printf("skipped\n");
2019 continue;
2020 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002021 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002022 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002023
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002024 for (j = 0; j < 10000; j++) {
2025 if (mode == MBEDTLS_AES_ENCRYPT) {
2026 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002027
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002028 memcpy(tmp, prv, 16);
2029 memcpy(prv, buf, 16);
2030 memcpy(buf, tmp, 16);
2031 }
2032
2033 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2034 if (ret != 0) {
2035 goto exit;
2036 }
2037
2038 }
2039
2040 if (memcmp(buf, aes_tests, 16) != 0) {
2041 ret = 1;
2042 goto exit;
2043 }
2044
2045 if (verbose != 0) {
2046 mbedtls_printf("passed\n");
2047 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 }
2049
Gilles Peskine449bd832023-01-11 14:50:10 +01002050 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002051 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002052 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002053 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002054#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002055
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002056#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002057 /*
2058 * CFB128 mode
2059 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002060 {
2061 static const int num_tests =
2062 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002063
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002064 for (i = 0; i < num_tests << 1; i++) {
2065 u = i >> 1;
2066 keybits = 128 + u * 64;
2067 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002068
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002069 if (verbose != 0) {
2070 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2071 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2072 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002073
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002074 memcpy(iv, aes_test_cfb128_iv, 16);
2075 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002076
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002077 offset = 0;
2078 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2079 /*
2080 * AES-192 is an optional feature that may be unavailable when
2081 * there is an alternative underlying implementation i.e. when
2082 * MBEDTLS_AES_ALT is defined.
2083 */
2084 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2085 mbedtls_printf("skipped\n");
2086 continue;
2087 } else if (ret != 0) {
2088 goto exit;
2089 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002091 if (mode == MBEDTLS_AES_DECRYPT) {
2092 memcpy(buf, aes_test_cfb128_ct[u], 64);
2093 aes_tests = aes_test_cfb128_pt;
2094 } else {
2095 memcpy(buf, aes_test_cfb128_pt, 64);
2096 aes_tests = aes_test_cfb128_ct[u];
2097 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002098
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002099 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2100 if (ret != 0) {
2101 goto exit;
2102 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002103
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002104 if (memcmp(buf, aes_tests, 64) != 0) {
2105 ret = 1;
2106 goto exit;
2107 }
2108
2109 if (verbose != 0) {
2110 mbedtls_printf("passed\n");
2111 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002112 }
2113
Gilles Peskine449bd832023-01-11 14:50:10 +01002114 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002115 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002116 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002117 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002118#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002119
Simon Butcherad4e4932018-04-29 00:43:47 +01002120#if defined(MBEDTLS_CIPHER_MODE_OFB)
2121 /*
2122 * OFB mode
2123 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002124 {
2125 static const int num_tests =
2126 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002127
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002128 for (i = 0; i < num_tests << 1; i++) {
2129 u = i >> 1;
2130 keybits = 128 + u * 64;
2131 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002132
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002133 if (verbose != 0) {
2134 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2135 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2136 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002137
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002138 memcpy(iv, aes_test_ofb_iv, 16);
2139 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002140
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002141 offset = 0;
2142 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2143 /*
2144 * AES-192 is an optional feature that may be unavailable when
2145 * there is an alternative underlying implementation i.e. when
2146 * MBEDTLS_AES_ALT is defined.
2147 */
2148 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2149 mbedtls_printf("skipped\n");
2150 continue;
2151 } else if (ret != 0) {
2152 goto exit;
2153 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002154
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002155 if (mode == MBEDTLS_AES_DECRYPT) {
2156 memcpy(buf, aes_test_ofb_ct[u], 64);
2157 aes_tests = aes_test_ofb_pt;
2158 } else {
2159 memcpy(buf, aes_test_ofb_pt, 64);
2160 aes_tests = aes_test_ofb_ct[u];
2161 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002162
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002163 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2164 if (ret != 0) {
2165 goto exit;
2166 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002167
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002168 if (memcmp(buf, aes_tests, 64) != 0) {
2169 ret = 1;
2170 goto exit;
2171 }
2172
2173 if (verbose != 0) {
2174 mbedtls_printf("passed\n");
2175 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002176 }
2177
Gilles Peskine449bd832023-01-11 14:50:10 +01002178 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002179 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002180 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002181 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002182#endif /* MBEDTLS_CIPHER_MODE_OFB */
2183
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002184#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002185 /*
2186 * CTR mode
2187 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002188 {
2189 static const int num_tests =
2190 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002191
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002192 for (i = 0; i < num_tests << 1; i++) {
2193 u = i >> 1;
2194 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 if (verbose != 0) {
2197 mbedtls_printf(" AES-CTR-128 (%s): ",
2198 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2199 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002200
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002201 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2202 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002203
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002204 offset = 0;
2205 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2206 goto exit;
2207 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002208
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002209 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002210
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002211 if (mode == MBEDTLS_AES_DECRYPT) {
2212 memcpy(buf, aes_test_ctr_ct[u], len);
2213 aes_tests = aes_test_ctr_pt[u];
2214 } else {
2215 memcpy(buf, aes_test_ctr_pt[u], len);
2216 aes_tests = aes_test_ctr_ct[u];
2217 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002218
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002219 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2220 stream_block, buf, buf);
2221 if (ret != 0) {
2222 goto exit;
2223 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002224
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002225 if (memcmp(buf, aes_tests, len) != 0) {
2226 ret = 1;
2227 goto exit;
2228 }
2229
2230 if (verbose != 0) {
2231 mbedtls_printf("passed\n");
2232 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002233 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002234 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002235
Gilles Peskine449bd832023-01-11 14:50:10 +01002236 if (verbose != 0) {
2237 mbedtls_printf("\n");
2238 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002239#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002240
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002241#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002242 /*
2243 * XTS mode
2244 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002245 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002246 static const int num_tests =
2247 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2248 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002249
Gilles Peskine449bd832023-01-11 14:50:10 +01002250 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002251
Gilles Peskine449bd832023-01-11 14:50:10 +01002252 for (i = 0; i < num_tests << 1; i++) {
2253 const unsigned char *data_unit;
2254 u = i >> 1;
2255 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002256
Gilles Peskine449bd832023-01-11 14:50:10 +01002257 if (verbose != 0) {
2258 mbedtls_printf(" AES-XTS-128 (%s): ",
2259 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2260 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002261
Gilles Peskine449bd832023-01-11 14:50:10 +01002262 memset(key, 0, sizeof(key));
2263 memcpy(key, aes_test_xts_key[u], 32);
2264 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002265
Gilles Peskine449bd832023-01-11 14:50:10 +01002266 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002267
Gilles Peskine449bd832023-01-11 14:50:10 +01002268 if (mode == MBEDTLS_AES_DECRYPT) {
2269 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2270 if (ret != 0) {
2271 goto exit;
2272 }
2273 memcpy(buf, aes_test_xts_ct32[u], len);
2274 aes_tests = aes_test_xts_pt32[u];
2275 } else {
2276 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2277 if (ret != 0) {
2278 goto exit;
2279 }
2280 memcpy(buf, aes_test_xts_pt32[u], len);
2281 aes_tests = aes_test_xts_ct32[u];
2282 }
2283
2284
2285 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2286 buf, buf);
2287 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002288 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002289 }
2290
2291 if (memcmp(buf, aes_tests, len) != 0) {
2292 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002293 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002294 }
2295
2296 if (verbose != 0) {
2297 mbedtls_printf("passed\n");
2298 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002299 }
2300
Gilles Peskine449bd832023-01-11 14:50:10 +01002301 if (verbose != 0) {
2302 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002303 }
2304
Gilles Peskine449bd832023-01-11 14:50:10 +01002305 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002306 }
2307#endif /* MBEDTLS_CIPHER_MODE_XTS */
2308
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002309 ret = 0;
2310
2311exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002312 if (ret != 0 && verbose != 0) {
2313 mbedtls_printf("failed\n");
2314 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002315
Gilles Peskine449bd832023-01-11 14:50:10 +01002316 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002317
Gilles Peskine449bd832023-01-11 14:50:10 +01002318 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002319}
2320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002321#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002323#endif /* MBEDTLS_AES_C */