blob: 7a6f2d91c2fd206e27dd68f7870115e895a59abd [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 Yu29c91ba2023-08-04 11:02:04 +0800659#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100660 for (i = 0; i < (keybits >> 5); i++) {
661 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000662 }
663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 case 10:
666
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000668 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
670 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
671 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
672 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
674 RK[5] = RK[1] ^ RK[4];
675 RK[6] = RK[2] ^ RK[5];
676 RK[7] = RK[3] ^ RK[6];
677 }
678 break;
679
Arto Kinnunen732ca322023-04-14 14:26:10 +0800680#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000681 case 12:
682
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000684 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
687 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
688 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000689
690 RK[7] = RK[1] ^ RK[6];
691 RK[8] = RK[2] ^ RK[7];
692 RK[9] = RK[3] ^ RK[8];
693 RK[10] = RK[4] ^ RK[9];
694 RK[11] = RK[5] ^ RK[10];
695 }
696 break;
697
698 case 14:
699
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000701 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
703 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
704 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
705 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
707 RK[9] = RK[1] ^ RK[8];
708 RK[10] = RK[2] ^ RK[9];
709 RK[11] = RK[3] ^ RK[10];
710
711 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
713 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
714 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
715 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000716
717 RK[13] = RK[5] ^ RK[12];
718 RK[14] = RK[6] ^ RK[13];
719 RK[15] = RK[7] ^ RK[14];
720 }
721 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800722#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000723 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800726#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000727}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200728#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000729
730/*
731 * AES key schedule (decryption)
732 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200733#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100734int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
735 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000736{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800737#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
738 int i, j;
739 uint32_t *SK;
740#endif
741 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000743 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800744
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000747
Gilles Peskine0de8f852023-03-16 17:14:59 +0100748 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100749 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000750
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200751 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200753 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000755
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200756 ctx->nr = cty.nr;
757
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100758#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
760 mbedtls_aesni_inverse_key((unsigned char *) RK,
761 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200762 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100763 }
764#endif
765
Jerry Yue096da12023-01-10 17:07:01 +0800766#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
767 if (mbedtls_aesce_has_support()) {
768 mbedtls_aesce_inverse_key(
769 (unsigned char *) RK,
770 (const unsigned char *) (cty.buf + cty.rk_offset),
771 ctx->nr);
772 goto exit;
773 }
774#endif
775
Jerry Yu29c91ba2023-08-04 11:02:04 +0800776#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100777 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000778
779 *RK++ = *SK++;
780 *RK++ = *SK++;
781 *RK++ = *SK++;
782 *RK++ = *SK++;
783
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
785 for (j = 0; j < 4; j++, SK++) {
786 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
787 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
788 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
789 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 }
791 }
792
793 *RK++ = *SK++;
794 *RK++ = *SK++;
795 *RK++ = *SK++;
796 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800797#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200798exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000800
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000802}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100803#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100804
805#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100806static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
807 unsigned int keybits,
808 const unsigned char **key1,
809 unsigned int *key1bits,
810 const unsigned char **key2,
811 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100812{
813 const unsigned int half_keybits = keybits / 2;
814 const unsigned int half_keybytes = half_keybits / 8;
815
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100817 case 256: break;
818 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100820 }
821
822 *key1bits = half_keybits;
823 *key2bits = half_keybits;
824 *key1 = &key[0];
825 *key2 = &key[half_keybytes];
826
827 return 0;
828}
829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
831 const unsigned char *key,
832 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100833{
Janos Follath24eed8d2019-11-22 13:21:35 +0000834 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100835 const unsigned char *key1, *key2;
836 unsigned int key1bits, key2bits;
837
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
839 &key2, &key2bits);
840 if (ret != 0) {
841 return ret;
842 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100843
844 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100845 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
846 if (ret != 0) {
847 return ret;
848 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100849
850 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100852}
853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
855 const unsigned char *key,
856 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100857{
Janos Follath24eed8d2019-11-22 13:21:35 +0000858 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100859 const unsigned char *key1, *key2;
860 unsigned int key1bits, key2bits;
861
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
863 &key2, &key2bits);
864 if (ret != 0) {
865 return ret;
866 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100867
868 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
870 if (ret != 0) {
871 return ret;
872 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100873
874 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100876}
877#endif /* MBEDTLS_CIPHER_MODE_XTS */
878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100880 do \
881 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
883 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
884 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
885 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100886 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
888 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
889 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
890 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100891 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
893 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
894 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
895 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100896 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
898 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
899 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
900 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
901 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100904 do \
905 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
907 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
908 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
909 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100910 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100911 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
912 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
913 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
914 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100915 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
917 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
918 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
919 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100920 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
922 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
923 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
924 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
925 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
927/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200928 * AES-ECB block encryption
929 */
930#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100931int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
932 const unsigned char input[16],
933 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934{
935 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100936 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200938 uint32_t X[4];
939 uint32_t Y[4];
940 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200941
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
943 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
944 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
945 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
948 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]);
949 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 +0200950 }
951
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 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 +0200953
Gilles Peskine5197c662020-08-26 17:03:24 +0200954 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
956 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
957 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
958 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200959
Gilles Peskine5197c662020-08-26 17:03:24 +0200960 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200965
Gilles Peskine5197c662020-08-26 17:03:24 +0200966 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
969 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
970 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200971
Gilles Peskine5197c662020-08-26 17:03:24 +0200972 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
974 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
975 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
976 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200977
Gilles Peskine449bd832023-01-11 14:50:10 +0100978 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
979 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
980 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
981 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000982
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500984
Gilles Peskine449bd832023-01-11 14:50:10 +0100985 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986}
987#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
988
989/*
990 * AES-ECB block decryption
991 */
992#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100993int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
994 const unsigned char input[16],
995 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996{
997 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100998 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +02001000 uint32_t X[4];
1001 uint32_t Y[4];
1002 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001003
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1005 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1006 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1007 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1010 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]);
1011 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 +02001012 }
1013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 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 +02001015
Gilles Peskine5197c662020-08-26 17:03:24 +02001016 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1018 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1019 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1020 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001021
Gilles Peskine5197c662020-08-26 17:03:24 +02001022 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001027
Gilles Peskine5197c662020-08-26 17:03:24 +02001028 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1031 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1032 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001033
Gilles Peskine5197c662020-08-26 17:03:24 +02001034 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1036 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1037 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1038 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001039
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1041 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1042 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1043 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001046
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001048}
1049#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1050
Gilles Peskine0de8f852023-03-16 17:14:59 +01001051#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001052/* VIA Padlock and our intrinsics-based implementation of AESNI require
1053 * the round keys to be aligned on a 16-byte boundary. We take care of this
1054 * before creating them, but the AES context may have moved (this can happen
1055 * if the library is called from a language with managed memory), and in later
1056 * calls it might have a different alignment with respect to 16-byte memory.
1057 * So we may need to realign.
1058 */
1059static void aes_maybe_realign(mbedtls_aes_context *ctx)
1060{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001061 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1062 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001063 memmove(ctx->buf + new_offset, // new address
1064 ctx->buf + ctx->rk_offset, // current address
1065 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1066 ctx->rk_offset = new_offset;
1067 }
1068}
1069#endif
1070
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001071/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001072 * AES-ECB block encryption/decryption
1073 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001074int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1075 int mode,
1076 const unsigned char input[16],
1077 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001078{
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001080 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001082
Gilles Peskine0de8f852023-03-16 17:14:59 +01001083#if defined(MAY_NEED_TO_ALIGN)
1084 aes_maybe_realign(ctx);
1085#endif
1086
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001087#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1089 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1090 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001091#endif
1092
Jerry Yu2bb3d812023-01-10 17:38:26 +08001093#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1094 if (mbedtls_aesce_has_support()) {
1095 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1096 }
1097#endif
1098
Jerry Yu9e628622023-08-17 11:20:09 +08001099#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001101 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001102 }
1103#endif
1104
Jerry Yu29c91ba2023-08-04 11:02:04 +08001105#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 if (mode == MBEDTLS_AES_ENCRYPT) {
1107 return mbedtls_internal_aes_encrypt(ctx, input, output);
1108 } else {
1109 return mbedtls_internal_aes_decrypt(ctx, input, output);
1110 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001111#endif
1112
Paul Bakker5121ce52009-01-03 21:22:43 +00001113}
1114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001116
Paul Bakker5121ce52009-01-03 21:22:43 +00001117/*
1118 * AES-CBC buffer encryption/decryption
1119 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001120int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1121 int mode,
1122 size_t length,
1123 unsigned char iv[16],
1124 const unsigned char *input,
1125 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001126{
Gilles Peskine7820a572021-07-07 21:08:28 +02001127 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001128 unsigned char temp[16];
1129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001131 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001133
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 if (length % 16) {
1135 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1136 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001137
Jerry Yu9e628622023-08-17 11:20:09 +08001138#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 if (aes_padlock_ace > 0) {
1140 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1141 return 0;
1142 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001143
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001144 // If padlock data misaligned, we just fall back to
1145 // unaccelerated mode
1146 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001147 }
1148#endif
1149
Dave Rodgman906c63c2023-06-14 17:53:51 +01001150 const unsigned char *ivp = iv;
1151
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 if (mode == MBEDTLS_AES_DECRYPT) {
1153 while (length > 0) {
1154 memcpy(temp, input, 16);
1155 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1156 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001157 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001159 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001160 * the result for the next block in CBC, and the cost of transferring that data from
1161 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001162 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001163
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001165
1166 input += 16;
1167 output += 16;
1168 length -= 16;
1169 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 } else {
1171 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001172 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001173
Gilles Peskine449bd832023-01-11 14:50:10 +01001174 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1175 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001176 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001177 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001178 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001179
1180 input += 16;
1181 output += 16;
1182 length -= 16;
1183 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001184 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001185 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001186 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001187
Gilles Peskine7820a572021-07-07 21:08:28 +02001188exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001190}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001191#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001192
Aorimn5f778012016-06-09 23:22:58 +02001193#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001194
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001195typedef unsigned char mbedtls_be128[16];
1196
1197/*
1198 * GF(2^128) multiplication function
1199 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001200 * This function multiplies a field element by x in the polynomial field
1201 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001202 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001203 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001204 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001205#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001206MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001207#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001208static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001209 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001210{
1211 uint64_t a, b, ra, rb;
1212
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 a = MBEDTLS_GET_UINT64_LE(x, 0);
1214 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001215
Gilles Peskine449bd832023-01-11 14:50:10 +01001216 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1217 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001218
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1220 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001221}
1222
Aorimn5f778012016-06-09 23:22:58 +02001223/*
1224 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001225 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001226 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001227 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001228 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001229#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001230MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001231#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001232int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1233 int mode,
1234 size_t length,
1235 const unsigned char data_unit[16],
1236 const unsigned char *input,
1237 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001238{
Janos Follath24eed8d2019-11-22 13:21:35 +00001239 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001240 size_t blocks = length / 16;
1241 size_t leftover = length % 16;
1242 unsigned char tweak[16];
1243 unsigned char prev_tweak[16];
1244 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001245
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001247 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001249
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001250 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 }
Aorimn5f778012016-06-09 23:22:58 +02001254
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001255 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001257 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 }
Aorimn5f778012016-06-09 23:22:58 +02001259
Jaeden Amerod82cd862018-04-28 15:02:45 +01001260 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1262 data_unit, tweak);
1263 if (ret != 0) {
1264 return ret;
1265 }
Aorimn5f778012016-06-09 23:22:58 +02001266
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001268 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001269 /* We are on the last block in a decrypt operation that has
1270 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001271 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001272 * the leftovers and then update the current tweak for use on this,
1273 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 memcpy(prev_tweak, tweak, sizeof(tweak));
1275 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276 }
1277
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001279
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1281 if (ret != 0) {
1282 return ret;
1283 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001284
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001286
1287 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289
1290 output += 16;
1291 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001292 }
1293
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001295 /* If we are on the leftover bytes in a decrypt operation, we need to
1296 * use the previous tweak for these bytes (as saved in prev_tweak). */
1297 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001298
Jaeden Amerod82cd862018-04-28 15:02:45 +01001299 /* We are now on the final part of the data unit, which doesn't divide
1300 * evenly by 16. It's time for ciphertext stealing. */
1301 size_t i;
1302 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001303
Jaeden Amerod82cd862018-04-28 15:02:45 +01001304 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001305 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001306 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001307 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001308 }
Aorimn5f778012016-06-09 23:22:58 +02001309
Dave Rodgman069e7f42022-11-24 19:37:26 +00001310 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001312
Jaeden Amerod82cd862018-04-28 15:02:45 +01001313 /* Copy ciphertext bytes from the previous block for input in this
1314 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001316
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1318 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001319 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 }
Aorimn5f778012016-06-09 23:22:58 +02001321
Jaeden Amerod82cd862018-04-28 15:02:45 +01001322 /* Write the result back to the previous block, overriding the previous
1323 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001325 }
1326
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001328}
1329#endif /* MBEDTLS_CIPHER_MODE_XTS */
1330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001331#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001332/*
1333 * AES-CFB128 buffer encryption/decryption
1334 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001335int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1336 int mode,
1337 size_t length,
1338 size_t *iv_off,
1339 unsigned char iv[16],
1340 const unsigned char *input,
1341 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001342{
Paul Bakker27fdf462011-06-09 13:55:13 +00001343 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001344 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001345 size_t n;
1346
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001348 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001350
1351 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001352
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 if (n > 15) {
1354 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1355 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001356
Gilles Peskine449bd832023-01-11 14:50:10 +01001357 if (mode == MBEDTLS_AES_DECRYPT) {
1358 while (length--) {
1359 if (n == 0) {
1360 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1361 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001362 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001364 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001365
1366 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001367 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001368 iv[n] = (unsigned char) c;
1369
Gilles Peskine449bd832023-01-11 14:50:10 +01001370 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001371 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 } else {
1373 while (length--) {
1374 if (n == 0) {
1375 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1376 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001377 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001379 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001380
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001382
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001384 }
1385 }
1386
1387 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001388 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001389
Gilles Peskine7820a572021-07-07 21:08:28 +02001390exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001392}
Paul Bakker556efba2014-01-24 15:38:12 +01001393
1394/*
1395 * AES-CFB8 buffer encryption/decryption
1396 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001397int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1398 int mode,
1399 size_t length,
1400 unsigned char iv[16],
1401 const unsigned char *input,
1402 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001403{
Gilles Peskine7820a572021-07-07 21:08:28 +02001404 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001405 unsigned char c;
1406 unsigned char ov[17];
1407
Gilles Peskine449bd832023-01-11 14:50:10 +01001408 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001409 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 }
1411 while (length--) {
1412 memcpy(ov, iv, 16);
1413 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1414 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001415 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 }
Paul Bakker556efba2014-01-24 15:38:12 +01001417
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001419 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 }
Paul Bakker556efba2014-01-24 15:38:12 +01001421
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001423
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001425 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001426 }
Paul Bakker556efba2014-01-24 15:38:12 +01001427
Gilles Peskine449bd832023-01-11 14:50:10 +01001428 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001429 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001430 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001431
Gilles Peskine7820a572021-07-07 21:08:28 +02001432exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001434}
Simon Butcher76a5b222018-04-22 22:57:27 +01001435#endif /* MBEDTLS_CIPHER_MODE_CFB */
1436
1437#if defined(MBEDTLS_CIPHER_MODE_OFB)
1438/*
1439 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1440 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001441int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1442 size_t length,
1443 size_t *iv_off,
1444 unsigned char iv[16],
1445 const unsigned char *input,
1446 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001447{
Simon Butcherad4e4932018-04-29 00:43:47 +01001448 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001449 size_t n;
1450
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001451 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001452
Gilles Peskine449bd832023-01-11 14:50:10 +01001453 if (n > 15) {
1454 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1455 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001456
Gilles Peskine449bd832023-01-11 14:50:10 +01001457 while (length--) {
1458 if (n == 0) {
1459 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1460 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001461 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001463 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001464 *output++ = *input++ ^ iv[n];
1465
Gilles Peskine449bd832023-01-11 14:50:10 +01001466 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001467 }
1468
1469 *iv_off = n;
1470
Simon Butcherad4e4932018-04-29 00:43:47 +01001471exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001472 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001473}
1474#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001475
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001476#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477/*
1478 * AES-CTR buffer encryption/decryption
1479 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001480int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1481 size_t length,
1482 size_t *nc_off,
1483 unsigned char nonce_counter[16],
1484 unsigned char stream_block[16],
1485 const unsigned char *input,
1486 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001487{
Paul Bakker369e14b2012-04-18 14:16:09 +00001488 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001489 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001490 size_t n;
1491
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001492 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001493
Gilles Peskine449bd832023-01-11 14:50:10 +01001494 if (n > 0x0F) {
1495 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1496 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001497
Gilles Peskine449bd832023-01-11 14:50:10 +01001498 while (length--) {
1499 if (n == 0) {
1500 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1501 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001502 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001503 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001504
Gilles Peskine449bd832023-01-11 14:50:10 +01001505 for (i = 16; i > 0; i--) {
1506 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001507 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001508 }
1509 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001510 }
1511 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001512 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001513
Gilles Peskine449bd832023-01-11 14:50:10 +01001514 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001515 }
1516
1517 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001518 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001519
Gilles Peskine7820a572021-07-07 21:08:28 +02001520exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001521 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001522}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001526
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001527#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001528/*
1529 * AES test vectors from:
1530 *
1531 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1532 */
Yanray Wang62c99912023-05-11 11:06:53 +08001533static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001534{
1535 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1536 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001537#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001538 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1539 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1540 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1541 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001542#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001543};
1544
Yanray Wang62c99912023-05-11 11:06:53 +08001545static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001546{
1547 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1548 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001549#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001550 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1551 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1552 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1553 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001554#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001555};
1556
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001557#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001558static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001559{
1560 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1561 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001562#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001563 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1564 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1565 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1566 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001567#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001568};
1569
Yanray Wang62c99912023-05-11 11:06:53 +08001570static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001571{
1572 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1573 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001574#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001575 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1576 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1577 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1578 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001579#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001580};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001581#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001582
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001583#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001584/*
1585 * AES-CFB128 test vectors from:
1586 *
1587 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1588 */
Yanray Wang62c99912023-05-11 11:06:53 +08001589static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001590{
1591 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1592 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001593#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001594 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1595 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1596 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1597 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1598 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1599 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1600 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001601#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001602};
1603
1604static const unsigned char aes_test_cfb128_iv[16] =
1605{
1606 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1607 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1608};
1609
1610static const unsigned char aes_test_cfb128_pt[64] =
1611{
1612 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1613 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1614 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1615 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1616 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1617 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1618 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1619 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1620};
1621
Yanray Wang62c99912023-05-11 11:06:53 +08001622static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001623{
1624 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1625 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1626 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1627 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1628 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1629 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1630 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1631 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001632#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001633 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1634 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1635 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1636 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1637 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1638 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1639 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1640 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1641 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1642 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1643 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1644 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1645 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1646 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1647 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1648 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001649#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001650};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001651#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001652
Simon Butcherad4e4932018-04-29 00:43:47 +01001653#if defined(MBEDTLS_CIPHER_MODE_OFB)
1654/*
1655 * AES-OFB test vectors from:
1656 *
Simon Butcher5db13622018-06-04 22:11:25 +01001657 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001658 */
Yanray Wang62c99912023-05-11 11:06:53 +08001659static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001660{
1661 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1662 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001663#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001664 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1665 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1666 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1667 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1668 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1669 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1670 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001671#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001672};
1673
1674static const unsigned char aes_test_ofb_iv[16] =
1675{
1676 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1677 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1678};
1679
1680static const unsigned char aes_test_ofb_pt[64] =
1681{
1682 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1683 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1684 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1685 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1686 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1687 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1688 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1689 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1690};
1691
Yanray Wang62c99912023-05-11 11:06:53 +08001692static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001693{
1694 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1695 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1696 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1697 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1698 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1699 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1700 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1701 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001702#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001703 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1704 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1705 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1706 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1707 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1708 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1709 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1710 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1711 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1712 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1713 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1714 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1715 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1716 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1717 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1718 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001719#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001720};
1721#endif /* MBEDTLS_CIPHER_MODE_OFB */
1722
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001723#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001724/*
1725 * AES-CTR test vectors from:
1726 *
1727 * http://www.faqs.org/rfcs/rfc3686.html
1728 */
1729
Yanray Wang62c99912023-05-11 11:06:53 +08001730static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001731{
1732 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1733 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1734 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1735 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1736 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1737 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1738};
1739
Yanray Wang62c99912023-05-11 11:06:53 +08001740static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001741{
1742 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1744 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1745 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1746 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1747 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1748};
1749
Yanray Wang62c99912023-05-11 11:06:53 +08001750static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001751{
1752 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1753 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001754 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1755 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1756 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1757 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1758
1759 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1760 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1761 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1762 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1763 0x20, 0x21, 0x22, 0x23 }
1764};
1765
Yanray Wang62c99912023-05-11 11:06:53 +08001766static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001767{
1768 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1769 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1770 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1771 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1772 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1773 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1774 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1775 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1776 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1777 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1778 0x25, 0xB2, 0x07, 0x2F }
1779};
1780
1781static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001782{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001783#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001784
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001785#if defined(MBEDTLS_CIPHER_MODE_XTS)
1786/*
1787 * AES-XTS test vectors from:
1788 *
1789 * IEEE P1619/D16 Annex B
1790 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1791 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1792 */
1793static const unsigned char aes_test_xts_key[][32] =
1794{
1795 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1799 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1800 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1801 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1802 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1803 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1804 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1805 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1806 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1807};
1808
1809static const unsigned char aes_test_xts_pt32[][32] =
1810{
1811 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1815 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1816 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1817 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1818 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1819 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1820 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1821 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1822 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1823};
1824
1825static const unsigned char aes_test_xts_ct32[][32] =
1826{
1827 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1828 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1829 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1830 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1831 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1832 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1833 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1834 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1835 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1836 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1837 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1838 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1839};
1840
1841static const unsigned char aes_test_xts_data_unit[][16] =
1842{
Gilles Peskine449bd832023-01-11 14:50:10 +01001843 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1845 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1847 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001849};
1850
1851#endif /* MBEDTLS_CIPHER_MODE_XTS */
1852
Paul Bakker5121ce52009-01-03 21:22:43 +00001853/*
1854 * Checkup routine
1855 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001856int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001857{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001858 int ret = 0, i, j, u, mode;
1859 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001860 unsigned char key[32];
1861 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001862 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001863#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1864 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001865 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001866#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001867#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001868 unsigned char prv[16];
1869#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001870#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1871 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001872 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001873#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001874#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001875 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001876#endif
1877#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001878 unsigned char nonce_counter[16];
1879 unsigned char stream_block[16];
1880#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001881 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001882
Gilles Peskine449bd832023-01-11 14:50:10 +01001883 memset(key, 0, 32);
1884 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001885
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001886 if (verbose != 0) {
1887#if defined(MBEDTLS_AES_ALT)
1888 mbedtls_printf(" AES note: alternative implementation.\n");
1889#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001890#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001891#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001892 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001893#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001894 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001895#else
1896#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1897#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001898 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1899 mbedtls_printf(" AES note: using AESNI.\n");
1900 } else
1901#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001902#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001903 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1904 mbedtls_printf(" AES note: using VIA Padlock.\n");
1905 } else
1906#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001907#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1908 if (mbedtls_aesce_has_support()) {
1909 mbedtls_printf(" AES note: using AESCE.\n");
1910 } else
1911#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001912 {
1913#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1914 mbedtls_printf(" AES note: built-in implementation.\n");
1915#endif
1916 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001917#endif /* MBEDTLS_AES_ALT */
1918 }
1919
Paul Bakker5121ce52009-01-03 21:22:43 +00001920 /*
1921 * ECB mode
1922 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001923 {
1924 static const int num_tests =
1925 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001926
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001927 for (i = 0; i < num_tests << 1; i++) {
1928 u = i >> 1;
1929 keybits = 128 + u * 64;
1930 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001931
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001932 if (verbose != 0) {
1933 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1934 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1935 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001936
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001937 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001938
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001939 if (mode == MBEDTLS_AES_DECRYPT) {
1940 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1941 aes_tests = aes_test_ecb_dec[u];
1942 } else {
1943 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1944 aes_tests = aes_test_ecb_enc[u];
1945 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001946
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001947 /*
1948 * AES-192 is an optional feature that may be unavailable when
1949 * there is an alternative underlying implementation i.e. when
1950 * MBEDTLS_AES_ALT is defined.
1951 */
1952 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1953 mbedtls_printf("skipped\n");
1954 continue;
1955 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001956 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001957 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001958
1959 for (j = 0; j < 10000; j++) {
1960 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1961 if (ret != 0) {
1962 goto exit;
1963 }
1964 }
1965
1966 if (memcmp(buf, aes_tests, 16) != 0) {
1967 ret = 1;
1968 goto exit;
1969 }
1970
1971 if (verbose != 0) {
1972 mbedtls_printf("passed\n");
1973 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001974 }
1975
Gilles Peskine449bd832023-01-11 14:50:10 +01001976 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001977 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001978 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001979 }
1980
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001981#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001982 /*
1983 * CBC mode
1984 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001985 {
1986 static const int num_tests =
1987 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001988
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001989 for (i = 0; i < num_tests << 1; i++) {
1990 u = i >> 1;
1991 keybits = 128 + u * 64;
1992 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001993
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001994 if (verbose != 0) {
1995 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1996 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001997 }
1998
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001999 memset(iv, 0, 16);
2000 memset(prv, 0, 16);
2001 memset(buf, 0, 16);
2002
2003 if (mode == MBEDTLS_AES_DECRYPT) {
2004 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2005 aes_tests = aes_test_cbc_dec[u];
2006 } else {
2007 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2008 aes_tests = aes_test_cbc_enc[u];
2009 }
2010
2011 /*
2012 * AES-192 is an optional feature that may be unavailable when
2013 * there is an alternative underlying implementation i.e. when
2014 * MBEDTLS_AES_ALT is defined.
2015 */
2016 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2017 mbedtls_printf("skipped\n");
2018 continue;
2019 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002020 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002021 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002022
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002023 for (j = 0; j < 10000; j++) {
2024 if (mode == MBEDTLS_AES_ENCRYPT) {
2025 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002026
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002027 memcpy(tmp, prv, 16);
2028 memcpy(prv, buf, 16);
2029 memcpy(buf, tmp, 16);
2030 }
2031
2032 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2033 if (ret != 0) {
2034 goto exit;
2035 }
2036
2037 }
2038
2039 if (memcmp(buf, aes_tests, 16) != 0) {
2040 ret = 1;
2041 goto exit;
2042 }
2043
2044 if (verbose != 0) {
2045 mbedtls_printf("passed\n");
2046 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002047 }
2048
Gilles Peskine449bd832023-01-11 14:50:10 +01002049 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002050 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002051 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002053#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002055#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002056 /*
2057 * CFB128 mode
2058 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002059 {
2060 static const int num_tests =
2061 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002062
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002063 for (i = 0; i < num_tests << 1; i++) {
2064 u = i >> 1;
2065 keybits = 128 + u * 64;
2066 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002068 if (verbose != 0) {
2069 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2070 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2071 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002072
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002073 memcpy(iv, aes_test_cfb128_iv, 16);
2074 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002075
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002076 offset = 0;
2077 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2078 /*
2079 * AES-192 is an optional feature that may be unavailable when
2080 * there is an alternative underlying implementation i.e. when
2081 * MBEDTLS_AES_ALT is defined.
2082 */
2083 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2084 mbedtls_printf("skipped\n");
2085 continue;
2086 } else if (ret != 0) {
2087 goto exit;
2088 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002089
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002090 if (mode == MBEDTLS_AES_DECRYPT) {
2091 memcpy(buf, aes_test_cfb128_ct[u], 64);
2092 aes_tests = aes_test_cfb128_pt;
2093 } else {
2094 memcpy(buf, aes_test_cfb128_pt, 64);
2095 aes_tests = aes_test_cfb128_ct[u];
2096 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002097
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002098 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2099 if (ret != 0) {
2100 goto exit;
2101 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002102
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002103 if (memcmp(buf, aes_tests, 64) != 0) {
2104 ret = 1;
2105 goto exit;
2106 }
2107
2108 if (verbose != 0) {
2109 mbedtls_printf("passed\n");
2110 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002111 }
2112
Gilles Peskine449bd832023-01-11 14:50:10 +01002113 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002114 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002115 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002116 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002117#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002118
Simon Butcherad4e4932018-04-29 00:43:47 +01002119#if defined(MBEDTLS_CIPHER_MODE_OFB)
2120 /*
2121 * OFB mode
2122 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002123 {
2124 static const int num_tests =
2125 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002126
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002127 for (i = 0; i < num_tests << 1; i++) {
2128 u = i >> 1;
2129 keybits = 128 + u * 64;
2130 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002131
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002132 if (verbose != 0) {
2133 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2134 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2135 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002136
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002137 memcpy(iv, aes_test_ofb_iv, 16);
2138 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002139
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002140 offset = 0;
2141 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2142 /*
2143 * AES-192 is an optional feature that may be unavailable when
2144 * there is an alternative underlying implementation i.e. when
2145 * MBEDTLS_AES_ALT is defined.
2146 */
2147 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2148 mbedtls_printf("skipped\n");
2149 continue;
2150 } else if (ret != 0) {
2151 goto exit;
2152 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002153
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002154 if (mode == MBEDTLS_AES_DECRYPT) {
2155 memcpy(buf, aes_test_ofb_ct[u], 64);
2156 aes_tests = aes_test_ofb_pt;
2157 } else {
2158 memcpy(buf, aes_test_ofb_pt, 64);
2159 aes_tests = aes_test_ofb_ct[u];
2160 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002161
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002162 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2163 if (ret != 0) {
2164 goto exit;
2165 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002166
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002167 if (memcmp(buf, aes_tests, 64) != 0) {
2168 ret = 1;
2169 goto exit;
2170 }
2171
2172 if (verbose != 0) {
2173 mbedtls_printf("passed\n");
2174 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002175 }
2176
Gilles Peskine449bd832023-01-11 14:50:10 +01002177 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002178 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002179 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002180 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002181#endif /* MBEDTLS_CIPHER_MODE_OFB */
2182
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002183#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002184 /*
2185 * CTR mode
2186 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002187 {
2188 static const int num_tests =
2189 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002190
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002191 for (i = 0; i < num_tests << 1; i++) {
2192 u = i >> 1;
2193 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002194
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002195 if (verbose != 0) {
2196 mbedtls_printf(" AES-CTR-128 (%s): ",
2197 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2198 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002199
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002200 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2201 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002202
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002203 offset = 0;
2204 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2205 goto exit;
2206 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002207
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002208 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002209
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002210 if (mode == MBEDTLS_AES_DECRYPT) {
2211 memcpy(buf, aes_test_ctr_ct[u], len);
2212 aes_tests = aes_test_ctr_pt[u];
2213 } else {
2214 memcpy(buf, aes_test_ctr_pt[u], len);
2215 aes_tests = aes_test_ctr_ct[u];
2216 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002217
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002218 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2219 stream_block, buf, buf);
2220 if (ret != 0) {
2221 goto exit;
2222 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002223
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002224 if (memcmp(buf, aes_tests, len) != 0) {
2225 ret = 1;
2226 goto exit;
2227 }
2228
2229 if (verbose != 0) {
2230 mbedtls_printf("passed\n");
2231 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002232 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002233 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002234
Gilles Peskine449bd832023-01-11 14:50:10 +01002235 if (verbose != 0) {
2236 mbedtls_printf("\n");
2237 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002238#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002239
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002240#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002241 /*
2242 * XTS mode
2243 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002244 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002245 static const int num_tests =
2246 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2247 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002248
Gilles Peskine449bd832023-01-11 14:50:10 +01002249 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002250
Gilles Peskine449bd832023-01-11 14:50:10 +01002251 for (i = 0; i < num_tests << 1; i++) {
2252 const unsigned char *data_unit;
2253 u = i >> 1;
2254 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002255
Gilles Peskine449bd832023-01-11 14:50:10 +01002256 if (verbose != 0) {
2257 mbedtls_printf(" AES-XTS-128 (%s): ",
2258 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2259 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002260
Gilles Peskine449bd832023-01-11 14:50:10 +01002261 memset(key, 0, sizeof(key));
2262 memcpy(key, aes_test_xts_key[u], 32);
2263 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002264
Gilles Peskine449bd832023-01-11 14:50:10 +01002265 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002266
Gilles Peskine449bd832023-01-11 14:50:10 +01002267 if (mode == MBEDTLS_AES_DECRYPT) {
2268 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2269 if (ret != 0) {
2270 goto exit;
2271 }
2272 memcpy(buf, aes_test_xts_ct32[u], len);
2273 aes_tests = aes_test_xts_pt32[u];
2274 } else {
2275 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2276 if (ret != 0) {
2277 goto exit;
2278 }
2279 memcpy(buf, aes_test_xts_pt32[u], len);
2280 aes_tests = aes_test_xts_ct32[u];
2281 }
2282
2283
2284 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2285 buf, buf);
2286 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002287 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002288 }
2289
2290 if (memcmp(buf, aes_tests, len) != 0) {
2291 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002292 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002293 }
2294
2295 if (verbose != 0) {
2296 mbedtls_printf("passed\n");
2297 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002298 }
2299
Gilles Peskine449bd832023-01-11 14:50:10 +01002300 if (verbose != 0) {
2301 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002302 }
2303
Gilles Peskine449bd832023-01-11 14:50:10 +01002304 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002305 }
2306#endif /* MBEDTLS_CIPHER_MODE_XTS */
2307
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002308 ret = 0;
2309
2310exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002311 if (ret != 0 && verbose != 0) {
2312 mbedtls_printf("failed\n");
2313 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002314
Gilles Peskine449bd832023-01-11 14:50:10 +01002315 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002316
Gilles Peskine449bd832023-01-11 14:50:10 +01002317 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002318}
2319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002320#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002321
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002322#endif /* MBEDTLS_AES_C */