blob: 968cd31386054e1a46d5d9f3c2d54322324042a4 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Jerry Yuba42b072023-08-10 12:53:26 +080037#if defined(__aarch64__)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yue62ff092023-08-16 14:15:00 +080043#if defined(__amd64__) || defined(__x86_64__) || \
44 defined(_M_X64) || defined(_M_AMD64)
Jerry Yu02b15192023-04-23 14:43:19 +080045#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080046#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080047#endif
48#endif
49
Jerry Yue62ff092023-08-16 14:15:00 +080050#if defined(__i386__) || defined(_M_IX86)
51#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
52#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080053#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080054
Jerry Yu1b4c7ed2023-08-17 11:25:17 +080055#if defined(MBEDTLS_PADLOCK_C) && \
56 (!defined(MBEDTLS_HAVE_ASM) || defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
Jerry Yu13696bb2023-08-10 13:36:32 +080057#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
58#endif
Jerry Yu02b15192023-04-23 14:43:19 +080059#endif
60
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000062#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000063#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020064#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000065#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010066#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080067#if defined(MBEDTLS_AESCE_C)
68#include "aesce.h"
69#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000070
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000071#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010072
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020074
Jerry Yu9e628622023-08-17 11:20:09 +080075#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000076static int aes_padlock_ace = -1;
77#endif
78
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000080/*
81 * Forward S-box
82 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010083#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
84 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000085static const unsigned char FSb[256] =
86{
87 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
88 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
89 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
90 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
91 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
92 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
93 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
94 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
95 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
96 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
97 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
98 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
99 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
100 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
101 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
102 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
103 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
104 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
105 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
106 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
107 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
108 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
109 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
110 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
111 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
112 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
113 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
114 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
115 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
116 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
117 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
118 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
119};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100120#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
121 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000122
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
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100193#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100194#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000195static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000196#undef V
197
Hanno Beckerad049a92017-06-19 16:31:54 +0100198#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000201static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000202#undef V
203
Gilles Peskine449bd832023-01-11 14:50:10 +0100204#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000205static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000206#undef V
207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000209static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000210#undef V
211
Hanno Becker177d3cf2017-06-07 15:52:48 +0100212#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200213
Dave Rodgman1be24632023-06-29 12:01:24 +0100214#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
215
Paul Bakker5121ce52009-01-03 21:22:43 +0000216#undef FT
217
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100218#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000219/*
220 * Reverse S-box
221 */
222static const unsigned char RSb[256] =
223{
224 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
225 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
226 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
227 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
228 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
229 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
230 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
231 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
232 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
233 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
234 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
235 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
236 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
237 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
238 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
239 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
240 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
241 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
242 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
243 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
244 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
245 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
246 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
247 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
248 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
249 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
250 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
251 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
252 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
253 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
254 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
255 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
256};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100257#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000258
259/*
260 * Reverse tables
261 */
262#define RT \
263\
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
265 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
266 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
267 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
268 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
269 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
270 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
271 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
272 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
273 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
274 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
275 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
276 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
277 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
278 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
279 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
280 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
281 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
282 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
283 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
284 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
285 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
286 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
287 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
288 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
289 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
290 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
291 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
292 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
293 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
294 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
295 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
296 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
297 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
298 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
299 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
300 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
301 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
302 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
303 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
304 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
305 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
306 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
307 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
308 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
309 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
310 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
311 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
312 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
313 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
314 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
315 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
316 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
317 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
318 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
319 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
320 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
321 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
322 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
323 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
324 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
325 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
326 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
327 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 +0000328
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100329#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
330
Gilles Peskine449bd832023-01-11 14:50:10 +0100331#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000332static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000333#undef V
334
Hanno Beckerad049a92017-06-19 16:31:54 +0100335#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000338static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000339#undef V
340
Gilles Peskine449bd832023-01-11 14:50:10 +0100341#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000342static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000343#undef V
344
Gilles Peskine449bd832023-01-11 14:50:10 +0100345#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000347#undef V
348
Hanno Becker177d3cf2017-06-07 15:52:48 +0100349#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200350
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800351#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
352
Paul Bakker5121ce52009-01-03 21:22:43 +0000353#undef RT
354
Dave Rodgman34152a42023-06-27 18:31:24 +0100355#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000356/*
357 * Round constants
358 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000359static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000360{
361 0x00000001, 0x00000002, 0x00000004, 0x00000008,
362 0x00000010, 0x00000020, 0x00000040, 0x00000080,
363 0x0000001B, 0x00000036
364};
Dave Rodgman34152a42023-06-27 18:31:24 +0100365#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000368
369/*
370 * Forward S-box & tables
371 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100372#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
373 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000374static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100375#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
376 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100377#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200378static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100379#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200380static uint32_t FT1[256];
381static uint32_t FT2[256];
382static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100383#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100384#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000385
386/*
387 * Reverse S-box & tables
388 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100389#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000390static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100391#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100392
393#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000394static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100395#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000396static uint32_t RT1[256];
397static uint32_t RT2[256];
398static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100399#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100400#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
Dave Rodgman8c753f92023-06-27 18:16:13 +0100402#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000403/*
404 * Round constants
405 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000406static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
408/*
409 * Tables generation code
410 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
412#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
413#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
415static int aes_init_done = 0;
416
Gilles Peskine449bd832023-01-11 14:50:10 +0100417static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000418{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800419 int i;
420 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800421 uint8_t pow[256];
422 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
424 /*
425 * compute pow and log tables over GF(2^8)
426 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000428 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800429 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800430 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 }
432
433 /*
434 * calculate the round constants
435 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800437 RCON[i] = x;
438 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 }
440
441 /*
442 * generate the forward and reverse S-boxes
443 */
444 FSb[0x00] = 0x63;
445 RSb[0x63] = 0x00;
446
Gilles Peskine449bd832023-01-11 14:50:10 +0100447 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000448 x = pow[255 - log[i]];
449
Yanray Wangfe944ce2023-06-26 18:16:01 +0800450 y = x; y = (y << 1) | (y >> 7);
451 x ^= y; y = (y << 1) | (y >> 7);
452 x ^= y; y = (y << 1) | (y >> 7);
453 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000454 x ^= y ^ 0x63;
455
Yanray Wangfe944ce2023-06-26 18:16:01 +0800456 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000457 RSb[x] = (unsigned char) i;
458 }
459
460 /*
461 * generate the forward and reverse tables
462 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000464 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800465 y = XTIME(x);
466 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 FT0[i] = ((uint32_t) y) ^
469 ((uint32_t) x << 8) ^
470 ((uint32_t) x << 16) ^
471 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
Hanno Beckerad049a92017-06-19 16:31:54 +0100473#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 FT1[i] = ROTL8(FT0[i]);
475 FT2[i] = ROTL8(FT1[i]);
476 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100477#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
479 x = RSb[i];
480
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100481#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
483 ((uint32_t) MUL(0x09, x) << 8) ^
484 ((uint32_t) MUL(0x0D, x) << 16) ^
485 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
Hanno Beckerad049a92017-06-19 16:31:54 +0100487#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100488 RT1[i] = ROTL8(RT0[i]);
489 RT2[i] = ROTL8(RT1[i]);
490 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100491#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100492#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000493 }
494}
495
Dave Rodgman8c753f92023-06-27 18:16:13 +0100496#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
497
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200498#undef ROTL8
499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
Hanno Beckerad049a92017-06-19 16:31:54 +0100502#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200503
Gilles Peskine449bd832023-01-11 14:50:10 +0100504#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
505#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
506#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200507
508#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100509#define AES_RT1(idx) ROTL8(RT0[idx])
510#define AES_RT2(idx) ROTL16(RT0[idx])
511#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200512
513#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100514#define AES_FT1(idx) ROTL8(FT0[idx])
515#define AES_FT2(idx) ROTL16(FT0[idx])
516#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200517
Hanno Becker177d3cf2017-06-07 15:52:48 +0100518#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200519
520#define AES_RT0(idx) RT0[idx]
521#define AES_RT1(idx) RT1[idx]
522#define AES_RT2(idx) RT2[idx]
523#define AES_RT3(idx) RT3[idx]
524
525#define AES_FT0(idx) FT0[idx]
526#define AES_FT1(idx) FT1[idx]
527#define AES_FT2(idx) FT2[idx]
528#define AES_FT3(idx) FT3[idx]
529
Hanno Becker177d3cf2017-06-07 15:52:48 +0100530#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200531
Gilles Peskine449bd832023-01-11 14:50:10 +0100532void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200533{
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200535}
536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200538{
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200540 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200542
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200544}
545
Jaeden Amero9366feb2018-05-29 18:55:17 +0100546#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100547void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100548{
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 mbedtls_aes_init(&ctx->crypt);
550 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100551}
552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100554{
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100556 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 }
Simon Butcher5201e412018-12-06 17:40:14 +0000558
Gilles Peskine449bd832023-01-11 14:50:10 +0100559 mbedtls_aes_free(&ctx->crypt);
560 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100561}
562#endif /* MBEDTLS_CIPHER_MODE_XTS */
563
Gilles Peskine0de8f852023-03-16 17:14:59 +0100564/* Some implementations need the round keys to be aligned.
565 * Return an offset to be added to buf, such that (buf + offset) is
566 * correctly aligned.
567 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
568 * i.e. an offset of 1 means 4 bytes and so on.
569 */
570#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100571 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100572#define MAY_NEED_TO_ALIGN
573#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100574
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100575#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
576 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100577static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
578{
579#if defined(MAY_NEED_TO_ALIGN)
580 int align_16_bytes = 0;
581
Jerry Yu9e628622023-08-17 11:20:09 +0800582#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100583 if (aes_padlock_ace == -1) {
584 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
585 }
586 if (aes_padlock_ace) {
587 align_16_bytes = 1;
588 }
589#endif
590
Gilles Peskine9c682e72023-03-16 17:21:33 +0100591#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100592 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
593 align_16_bytes = 1;
594 }
595#endif
596
597 if (align_16_bytes) {
598 /* These implementations needs 16-byte alignment
599 * for the round key array. */
600 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
601 if (delta == 0) {
602 return 0;
603 } else {
604 return 4 - delta; // 16 bytes = 4 uint32_t
605 }
606 }
607#else /* MAY_NEED_TO_ALIGN */
608 (void) buf;
609#endif /* MAY_NEED_TO_ALIGN */
610
611 return 0;
612}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100613#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
614 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100615
Paul Bakker5121ce52009-01-03 21:22:43 +0000616/*
617 * AES key schedule (encryption)
618 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200619#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100620int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
621 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000622{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800623#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Paul Bakker23986e52011-04-24 08:57:21 +0000624 unsigned int i;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800625#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000626 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800630#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000631 case 192: ctx->nr = 12; break;
632 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800633#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 }
636
Simon Butcher5201e412018-12-06 17:40:14 +0000637#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000639 aes_gen_tables();
640 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000641 }
642#endif
643
Gilles Peskine0de8f852023-03-16 17:14:59 +0100644 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100645 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100647#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100648 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
649 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
650 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100651#endif
652
Jerry Yu3f2fb712023-01-10 17:05:42 +0800653#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
654 if (mbedtls_aesce_has_support()) {
655 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
656 }
657#endif
658
Jerry Yucc068ae2023-08-16 16:07:57 +0800659/* When runtime detection enabled and plain C is disabled, compiler
660 reports `-Werror=return-type`. */
661#if defined(MBEDTLS_HAVE_X86) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && \
662 defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_AESNI_HAVE_CODE)
663 return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
664#endif
665
Jerry Yu29c91ba2023-08-04 11:02:04 +0800666#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 for (i = 0; i < (keybits >> 5); i++) {
668 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000669 }
670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000672 case 10:
673
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000675 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
677 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
678 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
679 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
681 RK[5] = RK[1] ^ RK[4];
682 RK[6] = RK[2] ^ RK[5];
683 RK[7] = RK[3] ^ RK[6];
684 }
685 break;
686
Arto Kinnunen732ca322023-04-14 14:26:10 +0800687#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000688 case 12:
689
Gilles Peskine449bd832023-01-11 14:50:10 +0100690 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000691 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
693 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
694 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
695 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
697 RK[7] = RK[1] ^ RK[6];
698 RK[8] = RK[2] ^ RK[7];
699 RK[9] = RK[3] ^ RK[8];
700 RK[10] = RK[4] ^ RK[9];
701 RK[11] = RK[5] ^ RK[10];
702 }
703 break;
704
705 case 14:
706
Gilles Peskine449bd832023-01-11 14:50:10 +0100707 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000708 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
710 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
711 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
712 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
714 RK[9] = RK[1] ^ RK[8];
715 RK[10] = RK[2] ^ RK[9];
716 RK[11] = RK[3] ^ RK[10];
717
718 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
720 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
721 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
722 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000723
724 RK[13] = RK[5] ^ RK[12];
725 RK[14] = RK[6] ^ RK[13];
726 RK[15] = RK[7] ^ RK[14];
727 }
728 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800729#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000730 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000731
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800733#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000734}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200735#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000736
737/*
738 * AES key schedule (decryption)
739 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200740#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100741int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
742 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000743{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800744#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
745 int i, j;
746 uint32_t *SK;
747#endif
748 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000750 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800751
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000754
Gilles Peskine0de8f852023-03-16 17:14:59 +0100755 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100756 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000757
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200758 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200760 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000762
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200763 ctx->nr = cty.nr;
764
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100765#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
767 mbedtls_aesni_inverse_key((unsigned char *) RK,
768 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200769 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100770 }
771#endif
772
Jerry Yue096da12023-01-10 17:07:01 +0800773#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
774 if (mbedtls_aesce_has_support()) {
775 mbedtls_aesce_inverse_key(
776 (unsigned char *) RK,
777 (const unsigned char *) (cty.buf + cty.rk_offset),
778 ctx->nr);
779 goto exit;
780 }
781#endif
782
Jerry Yu29c91ba2023-08-04 11:02:04 +0800783#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100784 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000785
786 *RK++ = *SK++;
787 *RK++ = *SK++;
788 *RK++ = *SK++;
789 *RK++ = *SK++;
790
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
792 for (j = 0; j < 4; j++, SK++) {
793 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
794 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
795 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
796 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 }
798 }
799
800 *RK++ = *SK++;
801 *RK++ = *SK++;
802 *RK++ = *SK++;
803 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800804#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200805exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100806 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000807
Gilles Peskine449bd832023-01-11 14:50:10 +0100808 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000809}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100810#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100811
812#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100813static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
814 unsigned int keybits,
815 const unsigned char **key1,
816 unsigned int *key1bits,
817 const unsigned char **key2,
818 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100819{
820 const unsigned int half_keybits = keybits / 2;
821 const unsigned int half_keybytes = half_keybits / 8;
822
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100824 case 256: break;
825 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100827 }
828
829 *key1bits = half_keybits;
830 *key2bits = half_keybits;
831 *key1 = &key[0];
832 *key2 = &key[half_keybytes];
833
834 return 0;
835}
836
Gilles Peskine449bd832023-01-11 14:50:10 +0100837int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
838 const unsigned char *key,
839 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100840{
Janos Follath24eed8d2019-11-22 13:21:35 +0000841 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100842 const unsigned char *key1, *key2;
843 unsigned int key1bits, key2bits;
844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
846 &key2, &key2bits);
847 if (ret != 0) {
848 return ret;
849 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100850
851 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
853 if (ret != 0) {
854 return ret;
855 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100856
857 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100859}
860
Gilles Peskine449bd832023-01-11 14:50:10 +0100861int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
862 const unsigned char *key,
863 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100864{
Janos Follath24eed8d2019-11-22 13:21:35 +0000865 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100866 const unsigned char *key1, *key2;
867 unsigned int key1bits, key2bits;
868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
870 &key2, &key2bits);
871 if (ret != 0) {
872 return ret;
873 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100874
875 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
877 if (ret != 0) {
878 return ret;
879 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100880
881 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100883}
884#endif /* MBEDTLS_CIPHER_MODE_XTS */
885
Gilles Peskine449bd832023-01-11 14:50:10 +0100886#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100887 do \
888 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
890 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
891 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
892 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100893 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
895 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
896 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
897 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100898 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
900 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
901 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
902 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100903 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
905 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
906 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
907 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
908 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100911 do \
912 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
914 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
915 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
916 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100917 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
919 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
920 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
921 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100922 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100923 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
924 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
925 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
926 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100927 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
929 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
930 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
931 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
932 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000933
934/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935 * AES-ECB block encryption
936 */
937#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100938int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
939 const unsigned char input[16],
940 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200941{
942 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100943 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200945 uint32_t X[4];
946 uint32_t Y[4];
947 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
950 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
951 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
952 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
955 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]);
956 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 +0200957 }
958
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 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 +0200960
Gilles Peskine5197c662020-08-26 17:03:24 +0200961 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
965 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200966
Gilles Peskine5197c662020-08-26 17:03:24 +0200967 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
971 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200972
Gilles Peskine5197c662020-08-26 17:03:24 +0200973 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
975 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
977 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200978
Gilles Peskine5197c662020-08-26 17:03:24 +0200979 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
981 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
982 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
983 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
986 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
987 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
988 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000989
Gilles Peskine449bd832023-01-11 14:50:10 +0100990 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500991
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200993}
994#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
995
996/*
997 * AES-ECB block decryption
998 */
999#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +01001000int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
1001 const unsigned char input[16],
1002 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001003{
1004 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +01001005 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001007 uint32_t X[4];
1008 uint32_t Y[4];
1009 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1012 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1013 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1014 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001015
Gilles Peskine449bd832023-01-11 14:50:10 +01001016 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1017 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]);
1018 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 +02001019 }
1020
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 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 +02001022
Gilles Peskine5197c662020-08-26 17:03:24 +02001023 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1027 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001028
Gilles Peskine5197c662020-08-26 17:03:24 +02001029 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1033 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001034
Gilles Peskine5197c662020-08-26 17:03:24 +02001035 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001036 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1037 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1039 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001040
Gilles Peskine5197c662020-08-26 17:03:24 +02001041 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001042 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1043 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1044 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1045 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001046
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1048 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1049 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1050 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001053
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001055}
1056#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1057
Gilles Peskine0de8f852023-03-16 17:14:59 +01001058#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001059/* VIA Padlock and our intrinsics-based implementation of AESNI require
1060 * the round keys to be aligned on a 16-byte boundary. We take care of this
1061 * before creating them, but the AES context may have moved (this can happen
1062 * if the library is called from a language with managed memory), and in later
1063 * calls it might have a different alignment with respect to 16-byte memory.
1064 * So we may need to realign.
1065 */
1066static void aes_maybe_realign(mbedtls_aes_context *ctx)
1067{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001068 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1069 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001070 memmove(ctx->buf + new_offset, // new address
1071 ctx->buf + ctx->rk_offset, // current address
1072 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1073 ctx->rk_offset = new_offset;
1074 }
1075}
1076#endif
1077
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001078/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001079 * AES-ECB block encryption/decryption
1080 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001081int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1082 int mode,
1083 const unsigned char input[16],
1084 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001085{
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001087 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001089
Gilles Peskine0de8f852023-03-16 17:14:59 +01001090#if defined(MAY_NEED_TO_ALIGN)
1091 aes_maybe_realign(ctx);
1092#endif
1093
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001094#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1096 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1097 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001098#endif
1099
Jerry Yu2bb3d812023-01-10 17:38:26 +08001100#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1101 if (mbedtls_aesce_has_support()) {
1102 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1103 }
1104#endif
1105
Jerry Yu9e628622023-08-17 11:20:09 +08001106#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001108 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001109 }
1110#endif
1111
Jerry Yucc068ae2023-08-16 16:07:57 +08001112/* When runtime detection enabled and plain C is disabled, compiler
1113 reports `-Werror=return-type`. */
Jerry Yu9e628622023-08-17 11:20:09 +08001114#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && \
1115 defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE) && defined(MBEDTLS_AESNI_HAVE_CODE)
Jerry Yucc068ae2023-08-16 16:07:57 +08001116 return MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED;
1117#endif
1118
Jerry Yu29c91ba2023-08-04 11:02:04 +08001119#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 if (mode == MBEDTLS_AES_ENCRYPT) {
1121 return mbedtls_internal_aes_encrypt(ctx, input, output);
1122 } else {
1123 return mbedtls_internal_aes_decrypt(ctx, input, output);
1124 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001125#endif
1126
Paul Bakker5121ce52009-01-03 21:22:43 +00001127}
1128
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001130
Paul Bakker5121ce52009-01-03 21:22:43 +00001131/*
1132 * AES-CBC buffer encryption/decryption
1133 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001134int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1135 int mode,
1136 size_t length,
1137 unsigned char iv[16],
1138 const unsigned char *input,
1139 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001140{
Gilles Peskine7820a572021-07-07 21:08:28 +02001141 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001142 unsigned char temp[16];
1143
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001145 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001147
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 if (length % 16) {
1149 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1150 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001151
Jerry Yu9e628622023-08-17 11:20:09 +08001152#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 if (aes_padlock_ace > 0) {
1154 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1155 return 0;
1156 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001157
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001158 // If padlock data misaligned, we just fall back to
1159 // unaccelerated mode
1160 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001161 }
1162#endif
1163
Dave Rodgman906c63c2023-06-14 17:53:51 +01001164 const unsigned char *ivp = iv;
1165
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 if (mode == MBEDTLS_AES_DECRYPT) {
1167 while (length > 0) {
1168 memcpy(temp, input, 16);
1169 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1170 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001171 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001173 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001174 * the result for the next block in CBC, and the cost of transferring that data from
1175 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001176 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001177
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001179
1180 input += 16;
1181 output += 16;
1182 length -= 16;
1183 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 } else {
1185 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001186 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001187
Gilles Peskine449bd832023-01-11 14:50:10 +01001188 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1189 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001190 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001192 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001193
1194 input += 16;
1195 output += 16;
1196 length -= 16;
1197 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001198 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001199 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001200 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001201
Gilles Peskine7820a572021-07-07 21:08:28 +02001202exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001204}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001205#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001206
Aorimn5f778012016-06-09 23:22:58 +02001207#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001208
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001209typedef unsigned char mbedtls_be128[16];
1210
1211/*
1212 * GF(2^128) multiplication function
1213 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001214 * This function multiplies a field element by x in the polynomial field
1215 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001216 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001217 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001218 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001219#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001220MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001221#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001222static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001223 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001224{
1225 uint64_t a, b, ra, rb;
1226
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 a = MBEDTLS_GET_UINT64_LE(x, 0);
1228 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001229
Gilles Peskine449bd832023-01-11 14:50:10 +01001230 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1231 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001232
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1234 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001235}
1236
Aorimn5f778012016-06-09 23:22:58 +02001237/*
1238 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001239 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001240 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001241 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001242 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001243#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001244MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001245#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001246int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1247 int mode,
1248 size_t length,
1249 const unsigned char data_unit[16],
1250 const unsigned char *input,
1251 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001252{
Janos Follath24eed8d2019-11-22 13:21:35 +00001253 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001254 size_t blocks = length / 16;
1255 size_t leftover = length % 16;
1256 unsigned char tweak[16];
1257 unsigned char prev_tweak[16];
1258 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001259
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001261 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001263
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001264 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 }
Aorimn5f778012016-06-09 23:22:58 +02001268
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001269 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001270 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001271 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 }
Aorimn5f778012016-06-09 23:22:58 +02001273
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001275 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1276 data_unit, tweak);
1277 if (ret != 0) {
1278 return ret;
1279 }
Aorimn5f778012016-06-09 23:22:58 +02001280
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001282 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001283 /* We are on the last block in a decrypt operation that has
1284 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001285 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001286 * the leftovers and then update the current tweak for use on this,
1287 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 memcpy(prev_tweak, tweak, sizeof(tweak));
1289 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001290 }
1291
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001293
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1295 if (ret != 0) {
1296 return ret;
1297 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001298
Gilles Peskine449bd832023-01-11 14:50:10 +01001299 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300
1301 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001302 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001303
1304 output += 16;
1305 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001306 }
1307
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001309 /* If we are on the leftover bytes in a decrypt operation, we need to
1310 * use the previous tweak for these bytes (as saved in prev_tweak). */
1311 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001312
Jaeden Amerod82cd862018-04-28 15:02:45 +01001313 /* We are now on the final part of the data unit, which doesn't divide
1314 * evenly by 16. It's time for ciphertext stealing. */
1315 size_t i;
1316 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001317
Jaeden Amerod82cd862018-04-28 15:02:45 +01001318 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001319 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001321 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001322 }
Aorimn5f778012016-06-09 23:22:58 +02001323
Dave Rodgman069e7f42022-11-24 19:37:26 +00001324 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001326
Jaeden Amerod82cd862018-04-28 15:02:45 +01001327 /* Copy ciphertext bytes from the previous block for input in this
1328 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001330
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1332 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001333 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 }
Aorimn5f778012016-06-09 23:22:58 +02001335
Jaeden Amerod82cd862018-04-28 15:02:45 +01001336 /* Write the result back to the previous block, overriding the previous
1337 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001339 }
1340
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001342}
1343#endif /* MBEDTLS_CIPHER_MODE_XTS */
1344
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001345#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001346/*
1347 * AES-CFB128 buffer encryption/decryption
1348 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001349int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1350 int mode,
1351 size_t length,
1352 size_t *iv_off,
1353 unsigned char iv[16],
1354 const unsigned char *input,
1355 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001356{
Paul Bakker27fdf462011-06-09 13:55:13 +00001357 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001358 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001359 size_t n;
1360
Gilles Peskine449bd832023-01-11 14:50:10 +01001361 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001362 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001364
1365 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001366
Gilles Peskine449bd832023-01-11 14:50:10 +01001367 if (n > 15) {
1368 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1369 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001370
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 if (mode == MBEDTLS_AES_DECRYPT) {
1372 while (length--) {
1373 if (n == 0) {
1374 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1375 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001376 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001378 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001379
1380 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001382 iv[n] = (unsigned char) c;
1383
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001385 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 } else {
1387 while (length--) {
1388 if (n == 0) {
1389 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1390 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001391 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001393 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001394
Gilles Peskine449bd832023-01-11 14:50:10 +01001395 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001396
Gilles Peskine449bd832023-01-11 14:50:10 +01001397 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001398 }
1399 }
1400
1401 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001402 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001403
Gilles Peskine7820a572021-07-07 21:08:28 +02001404exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001405 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001406}
Paul Bakker556efba2014-01-24 15:38:12 +01001407
1408/*
1409 * AES-CFB8 buffer encryption/decryption
1410 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001411int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1412 int mode,
1413 size_t length,
1414 unsigned char iv[16],
1415 const unsigned char *input,
1416 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001417{
Gilles Peskine7820a572021-07-07 21:08:28 +02001418 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001419 unsigned char c;
1420 unsigned char ov[17];
1421
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001423 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 }
1425 while (length--) {
1426 memcpy(ov, iv, 16);
1427 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1428 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001429 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001430 }
Paul Bakker556efba2014-01-24 15:38:12 +01001431
Gilles Peskine449bd832023-01-11 14:50:10 +01001432 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001433 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001434 }
Paul Bakker556efba2014-01-24 15:38:12 +01001435
Gilles Peskine449bd832023-01-11 14:50:10 +01001436 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001437
Gilles Peskine449bd832023-01-11 14:50:10 +01001438 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001439 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001440 }
Paul Bakker556efba2014-01-24 15:38:12 +01001441
Gilles Peskine449bd832023-01-11 14:50:10 +01001442 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001443 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001444 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001445
Gilles Peskine7820a572021-07-07 21:08:28 +02001446exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001447 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001448}
Simon Butcher76a5b222018-04-22 22:57:27 +01001449#endif /* MBEDTLS_CIPHER_MODE_CFB */
1450
1451#if defined(MBEDTLS_CIPHER_MODE_OFB)
1452/*
1453 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1454 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001455int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1456 size_t length,
1457 size_t *iv_off,
1458 unsigned char iv[16],
1459 const unsigned char *input,
1460 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001461{
Simon Butcherad4e4932018-04-29 00:43:47 +01001462 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001463 size_t n;
1464
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001465 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001466
Gilles Peskine449bd832023-01-11 14:50:10 +01001467 if (n > 15) {
1468 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1469 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001470
Gilles Peskine449bd832023-01-11 14:50:10 +01001471 while (length--) {
1472 if (n == 0) {
1473 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1474 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001475 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001476 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001477 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001478 *output++ = *input++ ^ iv[n];
1479
Gilles Peskine449bd832023-01-11 14:50:10 +01001480 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001481 }
1482
1483 *iv_off = n;
1484
Simon Butcherad4e4932018-04-29 00:43:47 +01001485exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001486 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001487}
1488#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001491/*
1492 * AES-CTR buffer encryption/decryption
1493 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001494int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1495 size_t length,
1496 size_t *nc_off,
1497 unsigned char nonce_counter[16],
1498 unsigned char stream_block[16],
1499 const unsigned char *input,
1500 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001501{
Paul Bakker369e14b2012-04-18 14:16:09 +00001502 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001503 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001504 size_t n;
1505
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001506 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001507
Gilles Peskine449bd832023-01-11 14:50:10 +01001508 if (n > 0x0F) {
1509 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1510 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001511
Gilles Peskine449bd832023-01-11 14:50:10 +01001512 while (length--) {
1513 if (n == 0) {
1514 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1515 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001516 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001517 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001518
Gilles Peskine449bd832023-01-11 14:50:10 +01001519 for (i = 16; i > 0; i--) {
1520 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001521 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001522 }
1523 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001524 }
1525 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001526 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001527
Gilles Peskine449bd832023-01-11 14:50:10 +01001528 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001529 }
1530
1531 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001532 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001533
Gilles Peskine7820a572021-07-07 21:08:28 +02001534exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001535 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001536}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001537#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001538
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001539#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001541#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001542/*
1543 * AES test vectors from:
1544 *
1545 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1546 */
Yanray Wang62c99912023-05-11 11:06:53 +08001547static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001548{
1549 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1550 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001551#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001552 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1553 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1554 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1555 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001556#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001557};
1558
Yanray Wang62c99912023-05-11 11:06:53 +08001559static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001560{
1561 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1562 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001563#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001564 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1565 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1566 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1567 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001568#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001569};
1570
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001571#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001572static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001573{
1574 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1575 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001576#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001577 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1578 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1579 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1580 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001581#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001582};
1583
Yanray Wang62c99912023-05-11 11:06:53 +08001584static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001585{
1586 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1587 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001588#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001589 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1590 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1591 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1592 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001593#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001594};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001595#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001596
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001597#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001598/*
1599 * AES-CFB128 test vectors from:
1600 *
1601 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1602 */
Yanray Wang62c99912023-05-11 11:06:53 +08001603static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001604{
1605 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1606 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001607#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001608 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1609 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1610 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1611 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1612 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1613 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1614 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001615#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001616};
1617
1618static const unsigned char aes_test_cfb128_iv[16] =
1619{
1620 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1621 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1622};
1623
1624static const unsigned char aes_test_cfb128_pt[64] =
1625{
1626 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1627 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1628 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1629 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1630 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1631 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1632 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1633 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1634};
1635
Yanray Wang62c99912023-05-11 11:06:53 +08001636static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001637{
1638 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1639 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1640 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1641 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1642 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1643 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1644 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1645 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001646#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001647 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1648 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1649 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1650 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1651 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1652 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1653 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1654 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1655 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1656 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1657 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1658 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1659 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1660 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1661 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1662 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001663#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001664};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001665#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001666
Simon Butcherad4e4932018-04-29 00:43:47 +01001667#if defined(MBEDTLS_CIPHER_MODE_OFB)
1668/*
1669 * AES-OFB test vectors from:
1670 *
Simon Butcher5db13622018-06-04 22:11:25 +01001671 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001672 */
Yanray Wang62c99912023-05-11 11:06:53 +08001673static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001674{
1675 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1676 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001677#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001678 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1679 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1680 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1681 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1682 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1683 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1684 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001685#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001686};
1687
1688static const unsigned char aes_test_ofb_iv[16] =
1689{
1690 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1691 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1692};
1693
1694static const unsigned char aes_test_ofb_pt[64] =
1695{
1696 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1697 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1698 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1699 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1700 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1701 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1702 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1703 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1704};
1705
Yanray Wang62c99912023-05-11 11:06:53 +08001706static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001707{
1708 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1709 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1710 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1711 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1712 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1713 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1714 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1715 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001716#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001717 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1718 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1719 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1720 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1721 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1722 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1723 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1724 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1725 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1726 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1727 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1728 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1729 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1730 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1731 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1732 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001733#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001734};
1735#endif /* MBEDTLS_CIPHER_MODE_OFB */
1736
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001737#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001738/*
1739 * AES-CTR test vectors from:
1740 *
1741 * http://www.faqs.org/rfcs/rfc3686.html
1742 */
1743
Yanray Wang62c99912023-05-11 11:06:53 +08001744static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001745{
1746 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1747 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1748 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1749 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1750 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1751 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1752};
1753
Yanray Wang62c99912023-05-11 11:06:53 +08001754static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001755{
1756 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1758 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1759 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1760 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1761 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1762};
1763
Yanray Wang62c99912023-05-11 11:06:53 +08001764static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001765{
1766 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1767 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001768 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1769 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1770 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1771 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1772
1773 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1774 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1775 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1776 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1777 0x20, 0x21, 0x22, 0x23 }
1778};
1779
Yanray Wang62c99912023-05-11 11:06:53 +08001780static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001781{
1782 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1783 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1784 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1785 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1786 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1787 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1788 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1789 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1790 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1791 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1792 0x25, 0xB2, 0x07, 0x2F }
1793};
1794
1795static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001796{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001797#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001798
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001799#if defined(MBEDTLS_CIPHER_MODE_XTS)
1800/*
1801 * AES-XTS test vectors from:
1802 *
1803 * IEEE P1619/D16 Annex B
1804 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1805 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1806 */
1807static const unsigned char aes_test_xts_key[][32] =
1808{
1809 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1813 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1814 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1815 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1816 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1817 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1818 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1819 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1820 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1821};
1822
1823static const unsigned char aes_test_xts_pt32[][32] =
1824{
1825 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1829 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1830 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1831 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1832 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1833 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1834 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1835 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1836 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1837};
1838
1839static const unsigned char aes_test_xts_ct32[][32] =
1840{
1841 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1842 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1843 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1844 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1845 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1846 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1847 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1848 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1849 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1850 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1851 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1852 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1853};
1854
1855static const unsigned char aes_test_xts_data_unit[][16] =
1856{
Gilles Peskine449bd832023-01-11 14:50:10 +01001857 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1859 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1861 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001863};
1864
1865#endif /* MBEDTLS_CIPHER_MODE_XTS */
1866
Paul Bakker5121ce52009-01-03 21:22:43 +00001867/*
1868 * Checkup routine
1869 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001870int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001871{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001872 int ret = 0, i, j, u, mode;
1873 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001874 unsigned char key[32];
1875 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001876 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001877#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1878 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001879 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001880#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001881#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001882 unsigned char prv[16];
1883#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001884#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1885 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001886 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001887#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001888#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001889 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001890#endif
1891#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001892 unsigned char nonce_counter[16];
1893 unsigned char stream_block[16];
1894#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001895 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
Gilles Peskine449bd832023-01-11 14:50:10 +01001897 memset(key, 0, 32);
1898 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001899
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001900 if (verbose != 0) {
1901#if defined(MBEDTLS_AES_ALT)
1902 mbedtls_printf(" AES note: alternative implementation.\n");
1903#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001904#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001905#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001906 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001907#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001908 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001909#else
1910#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1911#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001912 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1913 mbedtls_printf(" AES note: using AESNI.\n");
1914 } else
1915#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001916#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001917 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1918 mbedtls_printf(" AES note: using VIA Padlock.\n");
1919 } else
1920#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001921#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1922 if (mbedtls_aesce_has_support()) {
1923 mbedtls_printf(" AES note: using AESCE.\n");
1924 } else
1925#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001926 {
1927#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1928 mbedtls_printf(" AES note: built-in implementation.\n");
1929#endif
1930 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001931#endif /* MBEDTLS_AES_ALT */
1932 }
1933
Paul Bakker5121ce52009-01-03 21:22:43 +00001934 /*
1935 * ECB mode
1936 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001937 {
1938 static const int num_tests =
1939 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001941 for (i = 0; i < num_tests << 1; i++) {
1942 u = i >> 1;
1943 keybits = 128 + u * 64;
1944 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001945
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001946 if (verbose != 0) {
1947 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1948 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1949 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001950
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001951 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001952
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001953 if (mode == MBEDTLS_AES_DECRYPT) {
1954 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1955 aes_tests = aes_test_ecb_dec[u];
1956 } else {
1957 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1958 aes_tests = aes_test_ecb_enc[u];
1959 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001960
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001961 /*
1962 * AES-192 is an optional feature that may be unavailable when
1963 * there is an alternative underlying implementation i.e. when
1964 * MBEDTLS_AES_ALT is defined.
1965 */
1966 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1967 mbedtls_printf("skipped\n");
1968 continue;
1969 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001970 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001971 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001972
1973 for (j = 0; j < 10000; j++) {
1974 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1975 if (ret != 0) {
1976 goto exit;
1977 }
1978 }
1979
1980 if (memcmp(buf, aes_tests, 16) != 0) {
1981 ret = 1;
1982 goto exit;
1983 }
1984
1985 if (verbose != 0) {
1986 mbedtls_printf("passed\n");
1987 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001988 }
1989
Gilles Peskine449bd832023-01-11 14:50:10 +01001990 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001991 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001992 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 }
1994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001995#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001996 /*
1997 * CBC mode
1998 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001999 {
2000 static const int num_tests =
2001 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00002002
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002003 for (i = 0; i < num_tests << 1; i++) {
2004 u = i >> 1;
2005 keybits = 128 + u * 64;
2006 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01002007
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002008 if (verbose != 0) {
2009 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
2010 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00002011 }
2012
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002013 memset(iv, 0, 16);
2014 memset(prv, 0, 16);
2015 memset(buf, 0, 16);
2016
2017 if (mode == MBEDTLS_AES_DECRYPT) {
2018 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2019 aes_tests = aes_test_cbc_dec[u];
2020 } else {
2021 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2022 aes_tests = aes_test_cbc_enc[u];
2023 }
2024
2025 /*
2026 * AES-192 is an optional feature that may be unavailable when
2027 * there is an alternative underlying implementation i.e. when
2028 * MBEDTLS_AES_ALT is defined.
2029 */
2030 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2031 mbedtls_printf("skipped\n");
2032 continue;
2033 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002034 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002035 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002036
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002037 for (j = 0; j < 10000; j++) {
2038 if (mode == MBEDTLS_AES_ENCRYPT) {
2039 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002040
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002041 memcpy(tmp, prv, 16);
2042 memcpy(prv, buf, 16);
2043 memcpy(buf, tmp, 16);
2044 }
2045
2046 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2047 if (ret != 0) {
2048 goto exit;
2049 }
2050
2051 }
2052
2053 if (memcmp(buf, aes_tests, 16) != 0) {
2054 ret = 1;
2055 goto exit;
2056 }
2057
2058 if (verbose != 0) {
2059 mbedtls_printf("passed\n");
2060 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002061 }
2062
Gilles Peskine449bd832023-01-11 14:50:10 +01002063 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002064 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002065 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002066 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002067#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002068
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002069#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002070 /*
2071 * CFB128 mode
2072 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002073 {
2074 static const int num_tests =
2075 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002076
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002077 for (i = 0; i < num_tests << 1; i++) {
2078 u = i >> 1;
2079 keybits = 128 + u * 64;
2080 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002081
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002082 if (verbose != 0) {
2083 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2084 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2085 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002086
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002087 memcpy(iv, aes_test_cfb128_iv, 16);
2088 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002089
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002090 offset = 0;
2091 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2092 /*
2093 * AES-192 is an optional feature that may be unavailable when
2094 * there is an alternative underlying implementation i.e. when
2095 * MBEDTLS_AES_ALT is defined.
2096 */
2097 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2098 mbedtls_printf("skipped\n");
2099 continue;
2100 } else if (ret != 0) {
2101 goto exit;
2102 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002103
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002104 if (mode == MBEDTLS_AES_DECRYPT) {
2105 memcpy(buf, aes_test_cfb128_ct[u], 64);
2106 aes_tests = aes_test_cfb128_pt;
2107 } else {
2108 memcpy(buf, aes_test_cfb128_pt, 64);
2109 aes_tests = aes_test_cfb128_ct[u];
2110 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002111
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002112 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2113 if (ret != 0) {
2114 goto exit;
2115 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002116
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002117 if (memcmp(buf, aes_tests, 64) != 0) {
2118 ret = 1;
2119 goto exit;
2120 }
2121
2122 if (verbose != 0) {
2123 mbedtls_printf("passed\n");
2124 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002125 }
2126
Gilles Peskine449bd832023-01-11 14:50:10 +01002127 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002128 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002129 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002130 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002131#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002132
Simon Butcherad4e4932018-04-29 00:43:47 +01002133#if defined(MBEDTLS_CIPHER_MODE_OFB)
2134 /*
2135 * OFB mode
2136 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002137 {
2138 static const int num_tests =
2139 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002140
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002141 for (i = 0; i < num_tests << 1; i++) {
2142 u = i >> 1;
2143 keybits = 128 + u * 64;
2144 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002145
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002146 if (verbose != 0) {
2147 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2148 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2149 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002150
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002151 memcpy(iv, aes_test_ofb_iv, 16);
2152 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002153
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002154 offset = 0;
2155 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2156 /*
2157 * AES-192 is an optional feature that may be unavailable when
2158 * there is an alternative underlying implementation i.e. when
2159 * MBEDTLS_AES_ALT is defined.
2160 */
2161 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2162 mbedtls_printf("skipped\n");
2163 continue;
2164 } else if (ret != 0) {
2165 goto exit;
2166 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002167
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002168 if (mode == MBEDTLS_AES_DECRYPT) {
2169 memcpy(buf, aes_test_ofb_ct[u], 64);
2170 aes_tests = aes_test_ofb_pt;
2171 } else {
2172 memcpy(buf, aes_test_ofb_pt, 64);
2173 aes_tests = aes_test_ofb_ct[u];
2174 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002175
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002176 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2177 if (ret != 0) {
2178 goto exit;
2179 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002180
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002181 if (memcmp(buf, aes_tests, 64) != 0) {
2182 ret = 1;
2183 goto exit;
2184 }
2185
2186 if (verbose != 0) {
2187 mbedtls_printf("passed\n");
2188 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002189 }
2190
Gilles Peskine449bd832023-01-11 14:50:10 +01002191 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002192 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002193 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002194 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002195#endif /* MBEDTLS_CIPHER_MODE_OFB */
2196
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002197#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002198 /*
2199 * CTR mode
2200 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002201 {
2202 static const int num_tests =
2203 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002204
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002205 for (i = 0; i < num_tests << 1; i++) {
2206 u = i >> 1;
2207 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002208
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002209 if (verbose != 0) {
2210 mbedtls_printf(" AES-CTR-128 (%s): ",
2211 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2212 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002213
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002214 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2215 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002216
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002217 offset = 0;
2218 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2219 goto exit;
2220 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002221
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002222 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002223
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002224 if (mode == MBEDTLS_AES_DECRYPT) {
2225 memcpy(buf, aes_test_ctr_ct[u], len);
2226 aes_tests = aes_test_ctr_pt[u];
2227 } else {
2228 memcpy(buf, aes_test_ctr_pt[u], len);
2229 aes_tests = aes_test_ctr_ct[u];
2230 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002231
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002232 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2233 stream_block, buf, buf);
2234 if (ret != 0) {
2235 goto exit;
2236 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002237
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002238 if (memcmp(buf, aes_tests, len) != 0) {
2239 ret = 1;
2240 goto exit;
2241 }
2242
2243 if (verbose != 0) {
2244 mbedtls_printf("passed\n");
2245 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002246 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002247 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002248
Gilles Peskine449bd832023-01-11 14:50:10 +01002249 if (verbose != 0) {
2250 mbedtls_printf("\n");
2251 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002252#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002253
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002254#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002255 /*
2256 * XTS mode
2257 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002258 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002259 static const int num_tests =
2260 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2261 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002262
Gilles Peskine449bd832023-01-11 14:50:10 +01002263 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002264
Gilles Peskine449bd832023-01-11 14:50:10 +01002265 for (i = 0; i < num_tests << 1; i++) {
2266 const unsigned char *data_unit;
2267 u = i >> 1;
2268 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002269
Gilles Peskine449bd832023-01-11 14:50:10 +01002270 if (verbose != 0) {
2271 mbedtls_printf(" AES-XTS-128 (%s): ",
2272 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2273 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002274
Gilles Peskine449bd832023-01-11 14:50:10 +01002275 memset(key, 0, sizeof(key));
2276 memcpy(key, aes_test_xts_key[u], 32);
2277 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002278
Gilles Peskine449bd832023-01-11 14:50:10 +01002279 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002280
Gilles Peskine449bd832023-01-11 14:50:10 +01002281 if (mode == MBEDTLS_AES_DECRYPT) {
2282 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2283 if (ret != 0) {
2284 goto exit;
2285 }
2286 memcpy(buf, aes_test_xts_ct32[u], len);
2287 aes_tests = aes_test_xts_pt32[u];
2288 } else {
2289 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2290 if (ret != 0) {
2291 goto exit;
2292 }
2293 memcpy(buf, aes_test_xts_pt32[u], len);
2294 aes_tests = aes_test_xts_ct32[u];
2295 }
2296
2297
2298 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2299 buf, buf);
2300 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002301 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002302 }
2303
2304 if (memcmp(buf, aes_tests, len) != 0) {
2305 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002306 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002307 }
2308
2309 if (verbose != 0) {
2310 mbedtls_printf("passed\n");
2311 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002312 }
2313
Gilles Peskine449bd832023-01-11 14:50:10 +01002314 if (verbose != 0) {
2315 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002316 }
2317
Gilles Peskine449bd832023-01-11 14:50:10 +01002318 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002319 }
2320#endif /* MBEDTLS_CIPHER_MODE_XTS */
2321
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002322 ret = 0;
2323
2324exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002325 if (ret != 0 && verbose != 0) {
2326 mbedtls_printf("failed\n");
2327 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002328
Gilles Peskine449bd832023-01-11 14:50:10 +01002329 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002330
Gilles Peskine449bd832023-01-11 14:50:10 +01002331 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002332}
2333
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002334#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002336#endif /* MBEDTLS_AES_C */