blob: d2322298164cbd5f8c4e311bfcbe27270e7486a4 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010022 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000023 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Jerry Yu72fd0bd2023-08-18 16:31:01 +080037#if defined(MBEDTLS_ARCH_IS_ARM64)
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 Yud6e312d2023-08-18 17:19:51 +080043#if defined(MBEDTLS_ARCH_IS_X64)
Jerry Yu02b15192023-04-23 14:43:19 +080044#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080045#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080046#endif
47#endif
48
Jerry Yud6e312d2023-08-18 17:19:51 +080049#if defined(MBEDTLS_ARCH_IS_X86)
Jerry Yue62ff092023-08-16 14:15:00 +080050#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
51#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080052#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080053
Jerry Yu61fc5ed2023-08-18 17:28:48 +080054#if defined(MBEDTLS_PADLOCK_C)
55#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080056#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
57#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080058#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
59#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
60 "MBEDTLS_PADLOCK_C is set"
61#endif
62#endif
Jerry Yu02b15192023-04-23 14:43:19 +080063#endif
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000066#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000067#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000069#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010070#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080071#if defined(MBEDTLS_AESCE_C)
72#include "aesce.h"
73#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000074
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000075#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020078
Jerry Yu9e628622023-08-17 11:20:09 +080079#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000080static int aes_padlock_ace = -1;
81#endif
82
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000084/*
85 * Forward S-box
86 */
Dave Rodgman18ddf612023-10-04 14:03:12 +010087MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +000088{
89 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
90 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
91 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
92 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
93 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
94 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
95 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
96 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
97 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
98 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
99 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
100 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
101 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
102 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
103 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
104 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
105 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
106 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
107 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
108 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
109 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
110 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
111 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
112 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
113 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
114 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
115 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
116 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
117 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
118 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
119 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
120 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
121};
122
123/*
124 * Forward tables
125 */
126#define FT \
127\
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
129 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
130 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
131 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
132 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
133 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
134 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
135 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
136 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
137 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
138 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
139 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
140 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
141 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
142 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
143 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
144 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
145 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
146 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
147 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
148 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
149 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
150 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
151 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
152 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
153 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
154 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
155 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
156 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
157 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
158 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
159 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
160 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
161 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
162 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
163 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
164 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
165 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
166 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
167 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
168 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
169 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
170 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
171 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
172 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
173 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
174 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
175 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
176 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
177 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
178 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
179 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
180 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
181 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
182 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
183 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
184 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
185 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
186 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
187 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
188 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
189 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
190 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
191 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 +0000192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100194MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000195#undef V
196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100198MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000199#undef V
200
Gilles Peskine449bd832023-01-11 14:50:10 +0100201#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100202MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000203#undef V
204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100206MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000207#undef V
208
209#undef FT
210
211/*
212 * Reverse S-box
213 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100214MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000215{
216 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
217 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
218 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
219 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
220 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
221 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
222 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
223 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
224 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
225 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
226 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
227 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
228 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
229 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
230 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
231 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
232 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
233 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
234 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
235 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
236 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
237 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
238 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
239 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
240 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
241 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
242 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
243 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
244 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
245 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
246 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
247 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
248};
249
250/*
251 * Reverse tables
252 */
253#define RT \
254\
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
256 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
257 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
258 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
259 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
260 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
261 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
262 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
263 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
264 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
265 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
266 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
267 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
268 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
269 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
270 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
271 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
272 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
273 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
274 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
275 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
276 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
277 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
278 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
279 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
280 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
281 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
282 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
283 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
284 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
285 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
286 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
287 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
288 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
289 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
290 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
291 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
292 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
293 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
294 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
295 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
296 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
297 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
298 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
299 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
300 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
301 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
302 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
303 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
304 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
305 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
306 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
307 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
308 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
309 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
310 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
311 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
312 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
313 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
314 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
315 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
316 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
317 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
318 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 +0000319
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100320
Gilles Peskine449bd832023-01-11 14:50:10 +0100321#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100322MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000323#undef V
324
Gilles Peskine449bd832023-01-11 14:50:10 +0100325#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100326MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000327#undef V
328
Gilles Peskine449bd832023-01-11 14:50:10 +0100329#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100330MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000331#undef V
332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100334MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000335#undef V
336
337#undef RT
338
339/*
340 * Round constants
341 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100342MBEDTLS_MAYBE_UNUSED static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000343{
344 0x00000001, 0x00000002, 0x00000004, 0x00000008,
345 0x00000010, 0x00000020, 0x00000040, 0x00000080,
346 0x0000001B, 0x00000036
347};
348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351/*
352 * Forward S-box & tables
353 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100354MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
355MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
356MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
357MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
358MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360/*
361 * Reverse S-box & tables
362 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100363MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100364
Dave Rodgman18ddf612023-10-04 14:03:12 +0100365MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
366MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
367MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
368MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000369
370/*
371 * Round constants
372 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100373MBEDTLS_MAYBE_UNUSED static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
375/*
376 * Tables generation code
377 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100378#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
379#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
380#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
Dave Rodgman18ddf612023-10-04 14:03:12 +0100382MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
Dave Rodgman18ddf612023-10-04 14:03:12 +0100384MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000385{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800386 int i;
387 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800388 uint8_t pow[256];
389 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000390
391 /*
392 * compute pow and log tables over GF(2^8)
393 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800396 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800397 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000398 }
399
400 /*
401 * calculate the round constants
402 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800404 RCON[i] = x;
405 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 }
407
408 /*
409 * generate the forward and reverse S-boxes
410 */
411 FSb[0x00] = 0x63;
412 RSb[0x63] = 0x00;
413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 x = pow[255 - log[i]];
416
Yanray Wangfe944ce2023-06-26 18:16:01 +0800417 y = x; y = (y << 1) | (y >> 7);
418 x ^= y; y = (y << 1) | (y >> 7);
419 x ^= y; y = (y << 1) | (y >> 7);
420 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000421 x ^= y ^ 0x63;
422
Yanray Wangfe944ce2023-06-26 18:16:01 +0800423 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 RSb[x] = (unsigned char) i;
425 }
426
427 /*
428 * generate the forward and reverse tables
429 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800432 y = XTIME(x);
433 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 FT0[i] = ((uint32_t) y) ^
436 ((uint32_t) x << 8) ^
437 ((uint32_t) x << 16) ^
438 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
Hanno Beckerad049a92017-06-19 16:31:54 +0100440#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100441 FT1[i] = ROTL8(FT0[i]);
442 FT2[i] = ROTL8(FT1[i]);
443 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100444#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 x = RSb[i];
447
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100448#if !defined(MBEDTLS_AES_DECRYPT_ALT) || \
449 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
451 ((uint32_t) MUL(0x09, x) << 8) ^
452 ((uint32_t) MUL(0x0D, x) << 16) ^
453 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
Hanno Beckerad049a92017-06-19 16:31:54 +0100455#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 RT1[i] = ROTL8(RT0[i]);
457 RT2[i] = ROTL8(RT1[i]);
458 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100459#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman450c1ff2023-09-29 15:52:33 +0100460#endif \
461 /* !defined(MBEDTLS_AES_DECRYPT_ALT) || (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000462 }
463}
464
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200465#undef ROTL8
466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
Hanno Beckerad049a92017-06-19 16:31:54 +0100469#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200470
Gilles Peskine449bd832023-01-11 14:50:10 +0100471#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
472#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
473#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200474
475#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100476#define AES_RT1(idx) ROTL8(RT0[idx])
477#define AES_RT2(idx) ROTL16(RT0[idx])
478#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200479
480#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100481#define AES_FT1(idx) ROTL8(FT0[idx])
482#define AES_FT2(idx) ROTL16(FT0[idx])
483#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200484
Hanno Becker177d3cf2017-06-07 15:52:48 +0100485#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200486
487#define AES_RT0(idx) RT0[idx]
488#define AES_RT1(idx) RT1[idx]
489#define AES_RT2(idx) RT2[idx]
490#define AES_RT3(idx) RT3[idx]
491
492#define AES_FT0(idx) FT0[idx]
493#define AES_FT1(idx) FT1[idx]
494#define AES_FT2(idx) FT2[idx]
495#define AES_FT3(idx) FT3[idx]
496
Hanno Becker177d3cf2017-06-07 15:52:48 +0100497#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200498
Gilles Peskine449bd832023-01-11 14:50:10 +0100499void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200500{
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200502}
503
Gilles Peskine449bd832023-01-11 14:50:10 +0100504void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200505{
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200507 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200509
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200511}
512
Jaeden Amero9366feb2018-05-29 18:55:17 +0100513#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100514void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100515{
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 mbedtls_aes_init(&ctx->crypt);
517 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100518}
519
Gilles Peskine449bd832023-01-11 14:50:10 +0100520void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100521{
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100523 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 }
Simon Butcher5201e412018-12-06 17:40:14 +0000525
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 mbedtls_aes_free(&ctx->crypt);
527 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100528}
529#endif /* MBEDTLS_CIPHER_MODE_XTS */
530
Gilles Peskine0de8f852023-03-16 17:14:59 +0100531/* Some implementations need the round keys to be aligned.
532 * Return an offset to be added to buf, such that (buf + offset) is
533 * correctly aligned.
534 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
535 * i.e. an offset of 1 means 4 bytes and so on.
536 */
Jerry Yu96084472023-08-17 18:10:45 +0800537#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100538 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100539#define MAY_NEED_TO_ALIGN
540#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100541
Dave Rodgman18ddf612023-10-04 14:03:12 +0100542MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100543{
544#if defined(MAY_NEED_TO_ALIGN)
545 int align_16_bytes = 0;
546
Jerry Yu9e628622023-08-17 11:20:09 +0800547#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100548 if (aes_padlock_ace == -1) {
549 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
550 }
551 if (aes_padlock_ace) {
552 align_16_bytes = 1;
553 }
554#endif
555
Gilles Peskine9c682e72023-03-16 17:21:33 +0100556#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100557 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
558 align_16_bytes = 1;
559 }
560#endif
561
562 if (align_16_bytes) {
563 /* These implementations needs 16-byte alignment
564 * for the round key array. */
565 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
566 if (delta == 0) {
567 return 0;
568 } else {
569 return 4 - delta; // 16 bytes = 4 uint32_t
570 }
571 }
572#else /* MAY_NEED_TO_ALIGN */
573 (void) buf;
574#endif /* MAY_NEED_TO_ALIGN */
575
576 return 0;
577}
578
Paul Bakker5121ce52009-01-03 21:22:43 +0000579/*
580 * AES key schedule (encryption)
581 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200582#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100583int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
584 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000585{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000586 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800590#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000591 case 192: ctx->nr = 12; break;
592 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800593#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000595 }
596
Simon Butcher5201e412018-12-06 17:40:14 +0000597#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000599 aes_gen_tables();
600 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000601 }
602#endif
603
Gilles Peskine0de8f852023-03-16 17:14:59 +0100604 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100605 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100607#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
609 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
610 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100611#endif
612
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800613#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100614 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800615 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
616 }
617#endif
618
Jerry Yu29c91ba2023-08-04 11:02:04 +0800619#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800620 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000622 }
623
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 case 10:
626
Jerry Yu3a0f0442023-08-17 17:06:21 +0800627 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
630 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
631 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
632 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
634 RK[5] = RK[1] ^ RK[4];
635 RK[6] = RK[2] ^ RK[5];
636 RK[7] = RK[3] ^ RK[6];
637 }
638 break;
639
Arto Kinnunen732ca322023-04-14 14:26:10 +0800640#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000641 case 12:
642
Jerry Yu3a0f0442023-08-17 17:06:21 +0800643 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000644 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
646 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
647 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
648 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650 RK[7] = RK[1] ^ RK[6];
651 RK[8] = RK[2] ^ RK[7];
652 RK[9] = RK[3] ^ RK[8];
653 RK[10] = RK[4] ^ RK[9];
654 RK[11] = RK[5] ^ RK[10];
655 }
656 break;
657
658 case 14:
659
Jerry Yu3a0f0442023-08-17 17:06:21 +0800660 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000661 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
663 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
664 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
665 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
667 RK[9] = RK[1] ^ RK[8];
668 RK[10] = RK[2] ^ RK[9];
669 RK[11] = RK[3] ^ RK[10];
670
671 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
673 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
674 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
675 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000676
677 RK[13] = RK[5] ^ RK[12];
678 RK[14] = RK[6] ^ RK[13];
679 RK[15] = RK[7] ^ RK[14];
680 }
681 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800682#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000683 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000684
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800686#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000687}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200688#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000689
690/*
691 * AES key schedule (decryption)
692 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200693#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100694int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
695 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000696{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800697#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800698 uint32_t *SK;
699#endif
700 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000702 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800703
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200704
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
Gilles Peskine0de8f852023-03-16 17:14:59 +0100707 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100708 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000709
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200710 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200712 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000714
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200715 ctx->nr = cty.nr;
716
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100717#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
719 mbedtls_aesni_inverse_key((unsigned char *) RK,
720 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200721 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100722 }
723#endif
724
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800725#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100726 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800727 mbedtls_aesce_inverse_key(
728 (unsigned char *) RK,
729 (const unsigned char *) (cty.buf + cty.rk_offset),
730 ctx->nr);
731 goto exit;
732 }
733#endif
734
Jerry Yu29c91ba2023-08-04 11:02:04 +0800735#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100736 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000737
738 *RK++ = *SK++;
739 *RK++ = *SK++;
740 *RK++ = *SK++;
741 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800742 SK -= 8;
743 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
744 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
746 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
747 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
748 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000749 }
750 }
751
752 *RK++ = *SK++;
753 *RK++ = *SK++;
754 *RK++ = *SK++;
755 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800756#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200757exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000759
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000761}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100762#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100763
764#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100765static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
766 unsigned int keybits,
767 const unsigned char **key1,
768 unsigned int *key1bits,
769 const unsigned char **key2,
770 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100771{
772 const unsigned int half_keybits = keybits / 2;
773 const unsigned int half_keybytes = half_keybits / 8;
774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100776 case 256: break;
777 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100779 }
780
781 *key1bits = half_keybits;
782 *key2bits = half_keybits;
783 *key1 = &key[0];
784 *key2 = &key[half_keybytes];
785
786 return 0;
787}
788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
790 const unsigned char *key,
791 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100792{
Janos Follath24eed8d2019-11-22 13:21:35 +0000793 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100794 const unsigned char *key1, *key2;
795 unsigned int key1bits, key2bits;
796
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
798 &key2, &key2bits);
799 if (ret != 0) {
800 return ret;
801 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100802
803 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
805 if (ret != 0) {
806 return ret;
807 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808
809 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100811}
812
Gilles Peskine449bd832023-01-11 14:50:10 +0100813int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
814 const unsigned char *key,
815 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100816{
Janos Follath24eed8d2019-11-22 13:21:35 +0000817 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818 const unsigned char *key1, *key2;
819 unsigned int key1bits, key2bits;
820
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
822 &key2, &key2bits);
823 if (ret != 0) {
824 return ret;
825 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100826
827 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
829 if (ret != 0) {
830 return ret;
831 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100832
833 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100835}
836#endif /* MBEDTLS_CIPHER_MODE_XTS */
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100839 do \
840 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
842 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
843 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
844 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100845 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
847 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
848 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
849 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100850 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
852 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
853 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
854 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100855 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100856 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
857 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
858 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
859 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
860 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100863 do \
864 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
866 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
867 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
868 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100869 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
871 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
872 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
873 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100874 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
876 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
877 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
878 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100879 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
881 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
882 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
883 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
884 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000885
886/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200887 * AES-ECB block encryption
888 */
889#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100890int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
891 const unsigned char input[16],
892 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200893{
894 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100895 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200897 uint32_t X[4];
898 uint32_t Y[4];
899 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
902 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
903 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
904 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
907 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]);
908 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 +0200909 }
910
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 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 +0200912
Gilles Peskine5197c662020-08-26 17:03:24 +0200913 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
915 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
916 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
917 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200918
Gilles Peskine5197c662020-08-26 17:03:24 +0200919 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
921 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
922 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
923 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200924
Gilles Peskine5197c662020-08-26 17:03:24 +0200925 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
927 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
928 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
929 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930
Gilles Peskine5197c662020-08-26 17:03:24 +0200931 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
933 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
934 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
935 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
938 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
939 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
940 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200945}
946#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
947
948/*
949 * AES-ECB block decryption
950 */
951#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100952int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
953 const unsigned char input[16],
954 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955{
956 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100957 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200959 uint32_t X[4];
960 uint32_t Y[4];
961 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
964 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
965 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
966 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
969 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]);
970 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 +0200971 }
972
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 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 +0200974
Gilles Peskine5197c662020-08-26 17:03:24 +0200975 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
978 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
979 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200980
Gilles Peskine5197c662020-08-26 17:03:24 +0200981 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986
Gilles Peskine5197c662020-08-26 17:03:24 +0200987 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992
Gilles Peskine5197c662020-08-26 17:03:24 +0200993 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
995 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1000 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1001 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1002 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001007}
1008#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1009
Gilles Peskine148cad12023-03-16 13:08:42 +01001010/* VIA Padlock and our intrinsics-based implementation of AESNI require
1011 * the round keys to be aligned on a 16-byte boundary. We take care of this
1012 * before creating them, but the AES context may have moved (this can happen
1013 * if the library is called from a language with managed memory), and in later
1014 * calls it might have a different alignment with respect to 16-byte memory.
1015 * So we may need to realign.
1016 */
Dave Rodgman18ddf612023-10-04 14:03:12 +01001017MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +01001018{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001019 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1020 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001021 memmove(ctx->buf + new_offset, // new address
1022 ctx->buf + ctx->rk_offset, // current address
1023 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1024 ctx->rk_offset = new_offset;
1025 }
1026}
Gilles Peskine148cad12023-03-16 13:08:42 +01001027
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001028/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001029 * AES-ECB block encryption/decryption
1030 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001031int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1032 int mode,
1033 const unsigned char input[16],
1034 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001035{
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001037 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001039
Gilles Peskine0de8f852023-03-16 17:14:59 +01001040#if defined(MAY_NEED_TO_ALIGN)
1041 aes_maybe_realign(ctx);
1042#endif
1043
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001044#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1046 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1047 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001048#endif
1049
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001050#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001051 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001052 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1053 }
1054#endif
1055
Jerry Yu9e628622023-08-17 11:20:09 +08001056#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001058 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001059 }
1060#endif
1061
Jerry Yu29c91ba2023-08-04 11:02:04 +08001062#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 if (mode == MBEDTLS_AES_ENCRYPT) {
1064 return mbedtls_internal_aes_encrypt(ctx, input, output);
1065 } else {
1066 return mbedtls_internal_aes_decrypt(ctx, input, output);
1067 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001068#endif
1069
Paul Bakker5121ce52009-01-03 21:22:43 +00001070}
1071
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001073
Paul Bakker5121ce52009-01-03 21:22:43 +00001074/*
1075 * AES-CBC buffer encryption/decryption
1076 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001077int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1078 int mode,
1079 size_t length,
1080 unsigned char iv[16],
1081 const unsigned char *input,
1082 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001083{
Gilles Peskine7820a572021-07-07 21:08:28 +02001084 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001085 unsigned char temp[16];
1086
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001088 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001090
Paul Elliott2ad93672023-08-11 11:07:06 +01001091 /* Nothing to do if length is zero. */
1092 if (length == 0) {
1093 return 0;
1094 }
1095
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 if (length % 16) {
1097 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1098 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001099
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) {
1102 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1103 return 0;
1104 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001105
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001106 // If padlock data misaligned, we just fall back to
1107 // unaccelerated mode
1108 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001109 }
1110#endif
1111
Dave Rodgman906c63c2023-06-14 17:53:51 +01001112 const unsigned char *ivp = iv;
1113
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 if (mode == MBEDTLS_AES_DECRYPT) {
1115 while (length > 0) {
1116 memcpy(temp, input, 16);
1117 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1118 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001119 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001121 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001122 * the result for the next block in CBC, and the cost of transferring that data from
1123 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001124 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001125
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001127
1128 input += 16;
1129 output += 16;
1130 length -= 16;
1131 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 } else {
1133 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001134 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1137 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001138 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001140 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
1142 input += 16;
1143 output += 16;
1144 length -= 16;
1145 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001146 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001147 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001148 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001149
Gilles Peskine7820a572021-07-07 21:08:28 +02001150exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001152}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001153#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001154
Aorimn5f778012016-06-09 23:22:58 +02001155#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001156
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001157typedef unsigned char mbedtls_be128[16];
1158
1159/*
1160 * GF(2^128) multiplication function
1161 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001162 * This function multiplies a field element by x in the polynomial field
1163 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001164 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001165 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001166 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001167#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001168MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001169#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001170static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001171 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001172{
1173 uint64_t a, b, ra, rb;
1174
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 a = MBEDTLS_GET_UINT64_LE(x, 0);
1176 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001177
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1179 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1182 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001183}
1184
Aorimn5f778012016-06-09 23:22:58 +02001185/*
1186 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001187 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001188 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001189 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001190 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001191#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001192MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001193#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001194int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1195 int mode,
1196 size_t length,
1197 const unsigned char data_unit[16],
1198 const unsigned char *input,
1199 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001200{
Janos Follath24eed8d2019-11-22 13:21:35 +00001201 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001202 size_t blocks = length / 16;
1203 size_t leftover = length % 16;
1204 unsigned char tweak[16];
1205 unsigned char prev_tweak[16];
1206 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001207
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001209 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001210 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001211
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001212 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001214 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 }
Aorimn5f778012016-06-09 23:22:58 +02001216
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001217 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001219 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 }
Aorimn5f778012016-06-09 23:22:58 +02001221
Jaeden Amerod82cd862018-04-28 15:02:45 +01001222 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1224 data_unit, tweak);
1225 if (ret != 0) {
1226 return ret;
1227 }
Aorimn5f778012016-06-09 23:22:58 +02001228
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001230 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001231 /* We are on the last block in a decrypt operation that has
1232 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001233 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001234 * the leftovers and then update the current tweak for use on this,
1235 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001236 memcpy(prev_tweak, tweak, sizeof(tweak));
1237 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001238 }
1239
Gilles Peskine449bd832023-01-11 14:50:10 +01001240 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1243 if (ret != 0) {
1244 return ret;
1245 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001246
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001248
1249 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001251
1252 output += 16;
1253 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001254 }
1255
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001257 /* If we are on the leftover bytes in a decrypt operation, we need to
1258 * use the previous tweak for these bytes (as saved in prev_tweak). */
1259 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001260
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261 /* We are now on the final part of the data unit, which doesn't divide
1262 * evenly by 16. It's time for ciphertext stealing. */
1263 size_t i;
1264 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001265
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001267 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001269 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001270 }
Aorimn5f778012016-06-09 23:22:58 +02001271
Dave Rodgman069e7f42022-11-24 19:37:26 +00001272 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001274
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275 /* Copy ciphertext bytes from the previous block for input in this
1276 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001278
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1280 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 }
Aorimn5f778012016-06-09 23:22:58 +02001283
Jaeden Amerod82cd862018-04-28 15:02:45 +01001284 /* Write the result back to the previous block, overriding the previous
1285 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001287 }
1288
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001290}
1291#endif /* MBEDTLS_CIPHER_MODE_XTS */
1292
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001293#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001294/*
1295 * AES-CFB128 buffer encryption/decryption
1296 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001297int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1298 int mode,
1299 size_t length,
1300 size_t *iv_off,
1301 unsigned char iv[16],
1302 const unsigned char *input,
1303 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001304{
Paul Bakker27fdf462011-06-09 13:55:13 +00001305 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001306 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001307 size_t n;
1308
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001310 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001312
1313 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001314
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 if (n > 15) {
1316 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1317 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001318
Gilles Peskine449bd832023-01-11 14:50:10 +01001319 if (mode == MBEDTLS_AES_DECRYPT) {
1320 while (length--) {
1321 if (n == 0) {
1322 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1323 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001324 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001326 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001327
1328 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 iv[n] = (unsigned char) c;
1331
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001333 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 } else {
1335 while (length--) {
1336 if (n == 0) {
1337 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1338 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001339 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001341 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001342
Gilles Peskine449bd832023-01-11 14:50:10 +01001343 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001344
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001346 }
1347 }
1348
1349 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001350 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001351
Gilles Peskine7820a572021-07-07 21:08:28 +02001352exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001354}
Paul Bakker556efba2014-01-24 15:38:12 +01001355
1356/*
1357 * AES-CFB8 buffer encryption/decryption
1358 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001359int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1360 int mode,
1361 size_t length,
1362 unsigned char iv[16],
1363 const unsigned char *input,
1364 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001365{
Gilles Peskine7820a572021-07-07 21:08:28 +02001366 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001367 unsigned char c;
1368 unsigned char ov[17];
1369
Gilles Peskine449bd832023-01-11 14:50:10 +01001370 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001371 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 }
1373 while (length--) {
1374 memcpy(ov, iv, 16);
1375 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1376 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001377 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 }
Paul Bakker556efba2014-01-24 15:38:12 +01001379
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001381 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 }
Paul Bakker556efba2014-01-24 15:38:12 +01001383
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001385
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001387 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 }
Paul Bakker556efba2014-01-24 15:38:12 +01001389
Gilles Peskine449bd832023-01-11 14:50:10 +01001390 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001391 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001392 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001393
Gilles Peskine7820a572021-07-07 21:08:28 +02001394exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001395 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001396}
Simon Butcher76a5b222018-04-22 22:57:27 +01001397#endif /* MBEDTLS_CIPHER_MODE_CFB */
1398
1399#if defined(MBEDTLS_CIPHER_MODE_OFB)
1400/*
1401 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1402 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001403int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1404 size_t length,
1405 size_t *iv_off,
1406 unsigned char iv[16],
1407 const unsigned char *input,
1408 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001409{
Simon Butcherad4e4932018-04-29 00:43:47 +01001410 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001411 size_t n;
1412
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001413 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001414
Gilles Peskine449bd832023-01-11 14:50:10 +01001415 if (n > 15) {
1416 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1417 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001418
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 while (length--) {
1420 if (n == 0) {
1421 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1422 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001423 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001425 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001426 *output++ = *input++ ^ iv[n];
1427
Gilles Peskine449bd832023-01-11 14:50:10 +01001428 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001429 }
1430
1431 *iv_off = n;
1432
Simon Butcherad4e4932018-04-29 00:43:47 +01001433exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001434 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001435}
1436#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001438#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001439/*
1440 * AES-CTR buffer encryption/decryption
1441 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001442int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1443 size_t length,
1444 size_t *nc_off,
1445 unsigned char nonce_counter[16],
1446 unsigned char stream_block[16],
1447 const unsigned char *input,
1448 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001449{
Paul Bakker369e14b2012-04-18 14:16:09 +00001450 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001451 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001452 size_t n;
1453
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001454 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001455
Gilles Peskine449bd832023-01-11 14:50:10 +01001456 if (n > 0x0F) {
1457 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1458 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001459
Gilles Peskine449bd832023-01-11 14:50:10 +01001460 while (length--) {
1461 if (n == 0) {
1462 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1463 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001464 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001465 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001466
Gilles Peskine449bd832023-01-11 14:50:10 +01001467 for (i = 16; i > 0; i--) {
1468 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001469 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001470 }
1471 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001472 }
1473 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001474 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001475
Gilles Peskine449bd832023-01-11 14:50:10 +01001476 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477 }
1478
1479 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001480 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001481
Gilles Peskine7820a572021-07-07 21:08:28 +02001482exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001483 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001484}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001485#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001490/*
1491 * AES test vectors from:
1492 *
1493 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1494 */
Yanray Wang62c99912023-05-11 11:06:53 +08001495static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001496{
1497 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1498 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001499#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001500 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1501 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1502 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1503 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001504#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001505};
1506
Yanray Wang62c99912023-05-11 11:06:53 +08001507static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001508{
1509 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1510 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001511#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001512 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1513 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1514 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1515 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001516#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001517};
1518
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001520static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001521{
1522 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1523 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001524#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001525 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1526 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1527 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1528 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001529#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001530};
1531
Yanray Wang62c99912023-05-11 11:06:53 +08001532static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001533{
1534 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1535 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001536#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001537 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1538 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1539 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1540 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001541#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001542};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001543#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001544
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001545#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001546/*
1547 * AES-CFB128 test vectors from:
1548 *
1549 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1550 */
Yanray Wang62c99912023-05-11 11:06:53 +08001551static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001552{
1553 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1554 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001555#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001556 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1557 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1558 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1559 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1560 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1561 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1562 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001563#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001564};
1565
1566static const unsigned char aes_test_cfb128_iv[16] =
1567{
1568 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1569 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1570};
1571
1572static const unsigned char aes_test_cfb128_pt[64] =
1573{
1574 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1575 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1576 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1577 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1578 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1579 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1580 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1581 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1582};
1583
Yanray Wang62c99912023-05-11 11:06:53 +08001584static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001585{
1586 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1587 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1588 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1589 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1590 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1591 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1592 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1593 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
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 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1596 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1597 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1598 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1599 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1600 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1601 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1602 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1603 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1604 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1605 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1606 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1607 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1608 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1609 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1610 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001611#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001612};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001613#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001614
Simon Butcherad4e4932018-04-29 00:43:47 +01001615#if defined(MBEDTLS_CIPHER_MODE_OFB)
1616/*
1617 * AES-OFB test vectors from:
1618 *
Simon Butcher5db13622018-06-04 22:11:25 +01001619 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001620 */
Yanray Wang62c99912023-05-11 11:06:53 +08001621static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001622{
1623 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1624 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001625#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001626 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1627 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1628 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1629 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1630 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1631 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1632 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001633#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001634};
1635
1636static const unsigned char aes_test_ofb_iv[16] =
1637{
1638 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1639 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1640};
1641
1642static const unsigned char aes_test_ofb_pt[64] =
1643{
1644 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1645 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1646 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1647 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1648 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1649 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1650 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1651 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1652};
1653
Yanray Wang62c99912023-05-11 11:06:53 +08001654static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001655{
1656 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1657 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1658 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1659 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1660 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1661 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1662 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1663 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
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 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1666 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1667 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1668 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1669 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1670 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1671 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1672 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1673 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1674 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1675 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1676 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1677 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1678 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1679 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1680 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001681#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001682};
1683#endif /* MBEDTLS_CIPHER_MODE_OFB */
1684
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001685#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001686/*
1687 * AES-CTR test vectors from:
1688 *
1689 * http://www.faqs.org/rfcs/rfc3686.html
1690 */
1691
Yanray Wang62c99912023-05-11 11:06:53 +08001692static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001693{
1694 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1695 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1696 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1697 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1698 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1699 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1700};
1701
Yanray Wang62c99912023-05-11 11:06:53 +08001702static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001703{
1704 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1706 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1707 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1708 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1709 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1710};
1711
Yanray Wang62c99912023-05-11 11:06:53 +08001712static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001713{
1714 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1715 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001716 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1717 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1718 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1719 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1720
1721 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1722 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1723 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1724 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1725 0x20, 0x21, 0x22, 0x23 }
1726};
1727
Yanray Wang62c99912023-05-11 11:06:53 +08001728static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001729{
1730 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1731 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1732 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1733 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1734 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1735 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1736 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1737 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1738 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1739 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1740 0x25, 0xB2, 0x07, 0x2F }
1741};
1742
1743static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001744{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001745#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001746
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001747#if defined(MBEDTLS_CIPHER_MODE_XTS)
1748/*
1749 * AES-XTS test vectors from:
1750 *
1751 * IEEE P1619/D16 Annex B
1752 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1753 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1754 */
1755static const unsigned char aes_test_xts_key[][32] =
1756{
1757 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1761 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1762 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1763 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1764 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1765 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1766 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1767 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1768 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1769};
1770
1771static const unsigned char aes_test_xts_pt32[][32] =
1772{
1773 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1777 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1778 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1779 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1780 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1781 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1782 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1783 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1784 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1785};
1786
1787static const unsigned char aes_test_xts_ct32[][32] =
1788{
1789 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1790 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1791 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1792 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1793 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1794 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1795 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1796 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1797 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1798 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1799 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1800 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1801};
1802
1803static const unsigned char aes_test_xts_data_unit[][16] =
1804{
Gilles Peskine449bd832023-01-11 14:50:10 +01001805 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1807 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1809 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001811};
1812
1813#endif /* MBEDTLS_CIPHER_MODE_XTS */
1814
Paul Bakker5121ce52009-01-03 21:22:43 +00001815/*
1816 * Checkup routine
1817 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001818int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001819{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001820 int ret = 0, i, j, u, mode;
1821 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001822 unsigned char key[32];
1823 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001824 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001825#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1826 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001828#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001829#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001830 unsigned char prv[16];
1831#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001832#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1833 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001834 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001835#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001836#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001837 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001838#endif
1839#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001840 unsigned char nonce_counter[16];
1841 unsigned char stream_block[16];
1842#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001843 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001844
Gilles Peskine449bd832023-01-11 14:50:10 +01001845 memset(key, 0, 32);
1846 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001847
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001848 if (verbose != 0) {
1849#if defined(MBEDTLS_AES_ALT)
1850 mbedtls_printf(" AES note: alternative implementation.\n");
1851#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001852#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001853#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001854 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001855#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001856 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001857#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001858#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001859#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001860 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1861 mbedtls_printf(" AES note: using AESNI.\n");
1862 } else
1863#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001864#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001865 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1866 mbedtls_printf(" AES note: using VIA Padlock.\n");
1867 } else
1868#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001869#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001870 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001871 mbedtls_printf(" AES note: using AESCE.\n");
1872 } else
1873#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001874 {
1875#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1876 mbedtls_printf(" AES note: built-in implementation.\n");
1877#endif
1878 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001879#endif /* MBEDTLS_AES_ALT */
1880 }
1881
Paul Bakker5121ce52009-01-03 21:22:43 +00001882 /*
1883 * ECB mode
1884 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001885 {
1886 static const int num_tests =
1887 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001888
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001889 for (i = 0; i < num_tests << 1; i++) {
1890 u = i >> 1;
1891 keybits = 128 + u * 64;
1892 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001893
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001894 if (verbose != 0) {
1895 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1896 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1897 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001898
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001899 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001900
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001901 if (mode == MBEDTLS_AES_DECRYPT) {
1902 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1903 aes_tests = aes_test_ecb_dec[u];
1904 } else {
1905 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1906 aes_tests = aes_test_ecb_enc[u];
1907 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001908
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001909 /*
1910 * AES-192 is an optional feature that may be unavailable when
1911 * there is an alternative underlying implementation i.e. when
1912 * MBEDTLS_AES_ALT is defined.
1913 */
1914 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1915 mbedtls_printf("skipped\n");
1916 continue;
1917 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001918 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001919 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001920
1921 for (j = 0; j < 10000; j++) {
1922 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1923 if (ret != 0) {
1924 goto exit;
1925 }
1926 }
1927
1928 if (memcmp(buf, aes_tests, 16) != 0) {
1929 ret = 1;
1930 goto exit;
1931 }
1932
1933 if (verbose != 0) {
1934 mbedtls_printf("passed\n");
1935 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001936 }
1937
Gilles Peskine449bd832023-01-11 14:50:10 +01001938 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001939 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001940 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001941 }
1942
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001943#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001944 /*
1945 * CBC mode
1946 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001947 {
1948 static const int num_tests =
1949 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001950
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001951 for (i = 0; i < num_tests << 1; i++) {
1952 u = i >> 1;
1953 keybits = 128 + u * 64;
1954 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001955
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001956 if (verbose != 0) {
1957 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1958 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 }
1960
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001961 memset(iv, 0, 16);
1962 memset(prv, 0, 16);
1963 memset(buf, 0, 16);
1964
1965 if (mode == MBEDTLS_AES_DECRYPT) {
1966 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1967 aes_tests = aes_test_cbc_dec[u];
1968 } else {
1969 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1970 aes_tests = aes_test_cbc_enc[u];
1971 }
1972
1973 /*
1974 * AES-192 is an optional feature that may be unavailable when
1975 * there is an alternative underlying implementation i.e. when
1976 * MBEDTLS_AES_ALT is defined.
1977 */
1978 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1979 mbedtls_printf("skipped\n");
1980 continue;
1981 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001982 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001983 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001984
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001985 for (j = 0; j < 10000; j++) {
1986 if (mode == MBEDTLS_AES_ENCRYPT) {
1987 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001988
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001989 memcpy(tmp, prv, 16);
1990 memcpy(prv, buf, 16);
1991 memcpy(buf, tmp, 16);
1992 }
1993
1994 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1995 if (ret != 0) {
1996 goto exit;
1997 }
1998
1999 }
2000
2001 if (memcmp(buf, aes_tests, 16) != 0) {
2002 ret = 1;
2003 goto exit;
2004 }
2005
2006 if (verbose != 0) {
2007 mbedtls_printf("passed\n");
2008 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002009 }
2010
Gilles Peskine449bd832023-01-11 14:50:10 +01002011 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002012 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002013 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002014 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002015#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002016
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002017#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002018 /*
2019 * CFB128 mode
2020 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002021 {
2022 static const int num_tests =
2023 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002024
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002025 for (i = 0; i < num_tests << 1; i++) {
2026 u = i >> 1;
2027 keybits = 128 + u * 64;
2028 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002029
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002030 if (verbose != 0) {
2031 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2032 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2033 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002034
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002035 memcpy(iv, aes_test_cfb128_iv, 16);
2036 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002037
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002038 offset = 0;
2039 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2040 /*
2041 * AES-192 is an optional feature that may be unavailable when
2042 * there is an alternative underlying implementation i.e. when
2043 * MBEDTLS_AES_ALT is defined.
2044 */
2045 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2046 mbedtls_printf("skipped\n");
2047 continue;
2048 } else if (ret != 0) {
2049 goto exit;
2050 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002051
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002052 if (mode == MBEDTLS_AES_DECRYPT) {
2053 memcpy(buf, aes_test_cfb128_ct[u], 64);
2054 aes_tests = aes_test_cfb128_pt;
2055 } else {
2056 memcpy(buf, aes_test_cfb128_pt, 64);
2057 aes_tests = aes_test_cfb128_ct[u];
2058 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002059
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002060 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2061 if (ret != 0) {
2062 goto exit;
2063 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002064
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002065 if (memcmp(buf, aes_tests, 64) != 0) {
2066 ret = 1;
2067 goto exit;
2068 }
2069
2070 if (verbose != 0) {
2071 mbedtls_printf("passed\n");
2072 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002073 }
2074
Gilles Peskine449bd832023-01-11 14:50:10 +01002075 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002076 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002077 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002078 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002079#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002080
Simon Butcherad4e4932018-04-29 00:43:47 +01002081#if defined(MBEDTLS_CIPHER_MODE_OFB)
2082 /*
2083 * OFB mode
2084 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002085 {
2086 static const int num_tests =
2087 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002088
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002089 for (i = 0; i < num_tests << 1; i++) {
2090 u = i >> 1;
2091 keybits = 128 + u * 64;
2092 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002093
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002094 if (verbose != 0) {
2095 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2096 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2097 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002098
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002099 memcpy(iv, aes_test_ofb_iv, 16);
2100 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002101
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002102 offset = 0;
2103 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2104 /*
2105 * AES-192 is an optional feature that may be unavailable when
2106 * there is an alternative underlying implementation i.e. when
2107 * MBEDTLS_AES_ALT is defined.
2108 */
2109 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2110 mbedtls_printf("skipped\n");
2111 continue;
2112 } else if (ret != 0) {
2113 goto exit;
2114 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002115
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002116 if (mode == MBEDTLS_AES_DECRYPT) {
2117 memcpy(buf, aes_test_ofb_ct[u], 64);
2118 aes_tests = aes_test_ofb_pt;
2119 } else {
2120 memcpy(buf, aes_test_ofb_pt, 64);
2121 aes_tests = aes_test_ofb_ct[u];
2122 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002123
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002124 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2125 if (ret != 0) {
2126 goto exit;
2127 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002128
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002129 if (memcmp(buf, aes_tests, 64) != 0) {
2130 ret = 1;
2131 goto exit;
2132 }
2133
2134 if (verbose != 0) {
2135 mbedtls_printf("passed\n");
2136 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002137 }
2138
Gilles Peskine449bd832023-01-11 14:50:10 +01002139 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002140 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002141 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002142 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002143#endif /* MBEDTLS_CIPHER_MODE_OFB */
2144
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002145#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002146 /*
2147 * CTR mode
2148 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002149 {
2150 static const int num_tests =
2151 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002152
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002153 for (i = 0; i < num_tests << 1; i++) {
2154 u = i >> 1;
2155 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002156
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002157 if (verbose != 0) {
2158 mbedtls_printf(" AES-CTR-128 (%s): ",
2159 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2160 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002161
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002162 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2163 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002164
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002165 offset = 0;
2166 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2167 goto exit;
2168 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002169
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002170 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002171
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002172 if (mode == MBEDTLS_AES_DECRYPT) {
2173 memcpy(buf, aes_test_ctr_ct[u], len);
2174 aes_tests = aes_test_ctr_pt[u];
2175 } else {
2176 memcpy(buf, aes_test_ctr_pt[u], len);
2177 aes_tests = aes_test_ctr_ct[u];
2178 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002179
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002180 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2181 stream_block, buf, buf);
2182 if (ret != 0) {
2183 goto exit;
2184 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002185
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002186 if (memcmp(buf, aes_tests, len) != 0) {
2187 ret = 1;
2188 goto exit;
2189 }
2190
2191 if (verbose != 0) {
2192 mbedtls_printf("passed\n");
2193 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002194 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002195 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002196
Gilles Peskine449bd832023-01-11 14:50:10 +01002197 if (verbose != 0) {
2198 mbedtls_printf("\n");
2199 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002200#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002201
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002202#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002203 /*
2204 * XTS mode
2205 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002206 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002207 static const int num_tests =
2208 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2209 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002210
Gilles Peskine449bd832023-01-11 14:50:10 +01002211 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002212
Gilles Peskine449bd832023-01-11 14:50:10 +01002213 for (i = 0; i < num_tests << 1; i++) {
2214 const unsigned char *data_unit;
2215 u = i >> 1;
2216 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002217
Gilles Peskine449bd832023-01-11 14:50:10 +01002218 if (verbose != 0) {
2219 mbedtls_printf(" AES-XTS-128 (%s): ",
2220 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2221 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002222
Gilles Peskine449bd832023-01-11 14:50:10 +01002223 memset(key, 0, sizeof(key));
2224 memcpy(key, aes_test_xts_key[u], 32);
2225 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002226
Gilles Peskine449bd832023-01-11 14:50:10 +01002227 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002228
Gilles Peskine449bd832023-01-11 14:50:10 +01002229 if (mode == MBEDTLS_AES_DECRYPT) {
2230 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2231 if (ret != 0) {
2232 goto exit;
2233 }
2234 memcpy(buf, aes_test_xts_ct32[u], len);
2235 aes_tests = aes_test_xts_pt32[u];
2236 } else {
2237 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2238 if (ret != 0) {
2239 goto exit;
2240 }
2241 memcpy(buf, aes_test_xts_pt32[u], len);
2242 aes_tests = aes_test_xts_ct32[u];
2243 }
2244
2245
2246 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2247 buf, buf);
2248 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002249 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002250 }
2251
2252 if (memcmp(buf, aes_tests, len) != 0) {
2253 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002254 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002255 }
2256
2257 if (verbose != 0) {
2258 mbedtls_printf("passed\n");
2259 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002260 }
2261
Gilles Peskine449bd832023-01-11 14:50:10 +01002262 if (verbose != 0) {
2263 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002264 }
2265
Gilles Peskine449bd832023-01-11 14:50:10 +01002266 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002267 }
2268#endif /* MBEDTLS_CIPHER_MODE_XTS */
2269
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002270 ret = 0;
2271
2272exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002273 if (ret != 0 && verbose != 0) {
2274 mbedtls_printf("failed\n");
2275 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002276
Gilles Peskine449bd832023-01-11 14:50:10 +01002277 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002278
Gilles Peskine449bd832023-01-11 14:50:10 +01002279 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002280}
2281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002282#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002284#endif /* MBEDTLS_AES_C */