blob: 592ca6416ff9614548daee24c28685b219a0e827 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010022 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000023 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000037#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000040#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080042#if defined(MBEDTLS_AESCE_C)
43#include "aesce.h"
44#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020049
Gilles Peskine0f454e42023-03-16 14:58:46 +010050#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000051static int aes_padlock_ace = -1;
52#endif
53
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000055/*
56 * Forward S-box
57 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010058#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
59 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000060static const unsigned char FSb[256] =
61{
62 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
63 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
64 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
65 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
66 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
67 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
68 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
69 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
70 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
71 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
72 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
73 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
74 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
75 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
76 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
77 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
78 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
79 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
80 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
81 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
82 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
83 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
84 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
85 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
86 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
87 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
88 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
89 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
90 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
91 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
92 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
93 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
94};
Dave Rodgmanafe85db2023-06-29 12:07:11 +010095#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
96 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +000097
98/*
99 * Forward tables
100 */
101#define FT \
102\
Gilles Peskine449bd832023-01-11 14:50:10 +0100103 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
104 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
105 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
106 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
107 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
108 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
109 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
110 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
111 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
112 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
113 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
114 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
115 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
116 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
117 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
118 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
119 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
120 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
121 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
122 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
123 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
124 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
125 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
126 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
127 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
128 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
129 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
130 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
131 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
132 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
133 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
134 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
135 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
136 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
137 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
138 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
139 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
140 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
141 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
142 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
143 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
144 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
145 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
146 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
147 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
148 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
149 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
150 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
151 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
152 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
153 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
154 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
155 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
156 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
157 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
158 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
159 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
160 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
161 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
162 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
163 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
164 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
165 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
166 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 +0000167
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100168#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100169#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000170static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000171#undef V
172
Hanno Beckerad049a92017-06-19 16:31:54 +0100173#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000176static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000177#undef V
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000180static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000181#undef V
182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000184static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000185#undef V
186
Hanno Becker177d3cf2017-06-07 15:52:48 +0100187#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200188
Dave Rodgman1be24632023-06-29 12:01:24 +0100189#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
190
Paul Bakker5121ce52009-01-03 21:22:43 +0000191#undef FT
192
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100193#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000194/*
195 * Reverse S-box
196 */
197static const unsigned char RSb[256] =
198{
199 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
200 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
201 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
202 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
203 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
204 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
205 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
206 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
207 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
208 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
209 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
210 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
211 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
212 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
213 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
214 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
215 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
216 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
217 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
218 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
219 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
220 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
221 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
222 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
223 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
224 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
225 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
226 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
227 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
228 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
229 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
230 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
231};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100232#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
234/*
235 * Reverse tables
236 */
237#define RT \
238\
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
240 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
241 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
242 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
243 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
244 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
245 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
246 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
247 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
248 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
249 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
250 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
251 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
252 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
253 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
254 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
255 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
256 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
257 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
258 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
259 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
260 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
261 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
262 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
263 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
264 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
265 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
266 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
267 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
268 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
269 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
270 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
271 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
272 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
273 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
274 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
275 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
276 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
277 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
278 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
279 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
280 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
281 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
282 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
283 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
284 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
285 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
286 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
287 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
288 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
289 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
290 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
291 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
292 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
293 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
294 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
295 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
296 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
297 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
298 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
299 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
300 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
301 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
302 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 +0000303
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100304#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Hanno Beckerad049a92017-06-19 16:31:54 +0100310#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000313static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000314#undef V
315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000317static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000318#undef V
319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000322#undef V
323
Hanno Becker177d3cf2017-06-07 15:52:48 +0100324#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200325
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800326#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
327
Paul Bakker5121ce52009-01-03 21:22:43 +0000328#undef RT
329
Dave Rodgman34152a42023-06-27 18:31:24 +0100330#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000331/*
332 * Round constants
333 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000335{
336 0x00000001, 0x00000002, 0x00000004, 0x00000008,
337 0x00000010, 0x00000020, 0x00000040, 0x00000080,
338 0x0000001B, 0x00000036
339};
Dave Rodgman34152a42023-06-27 18:31:24 +0100340#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344/*
345 * Forward S-box & tables
346 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100347#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
348 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000349static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100350#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
351 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100352#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200353static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100354#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200355static uint32_t FT1[256];
356static uint32_t FT2[256];
357static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100358#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100359#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
361/*
362 * Reverse S-box & tables
363 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100364#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000365static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100366#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100367
368#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000369static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100370#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000371static uint32_t RT1[256];
372static uint32_t RT2[256];
373static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100374#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100375#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
Dave Rodgman8c753f92023-06-27 18:16:13 +0100377#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000378/*
379 * Round constants
380 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000381static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000382
383/*
384 * Tables generation code
385 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100386#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
387#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
388#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
390static int aes_init_done = 0;
391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000393{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800394 int i;
395 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800396 uint8_t pow[256];
397 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
399 /*
400 * compute pow and log tables over GF(2^8)
401 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800404 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800405 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 }
407
408 /*
409 * calculate the round constants
410 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800412 RCON[i] = x;
413 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 }
415
416 /*
417 * generate the forward and reverse S-boxes
418 */
419 FSb[0x00] = 0x63;
420 RSb[0x63] = 0x00;
421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 x = pow[255 - log[i]];
424
Yanray Wangfe944ce2023-06-26 18:16:01 +0800425 y = x; y = (y << 1) | (y >> 7);
426 x ^= y; y = (y << 1) | (y >> 7);
427 x ^= y; y = (y << 1) | (y >> 7);
428 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 x ^= y ^ 0x63;
430
Yanray Wangfe944ce2023-06-26 18:16:01 +0800431 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 RSb[x] = (unsigned char) i;
433 }
434
435 /*
436 * generate the forward and reverse tables
437 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800440 y = XTIME(x);
441 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 FT0[i] = ((uint32_t) y) ^
444 ((uint32_t) x << 8) ^
445 ((uint32_t) x << 16) ^
446 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Hanno Beckerad049a92017-06-19 16:31:54 +0100448#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 FT1[i] = ROTL8(FT0[i]);
450 FT2[i] = ROTL8(FT1[i]);
451 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100452#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
454 x = RSb[i];
455
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100456#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
458 ((uint32_t) MUL(0x09, x) << 8) ^
459 ((uint32_t) MUL(0x0D, x) << 16) ^
460 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Hanno Beckerad049a92017-06-19 16:31:54 +0100462#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 RT1[i] = ROTL8(RT0[i]);
464 RT2[i] = ROTL8(RT1[i]);
465 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100466#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100467#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 }
469}
470
Dave Rodgman8c753f92023-06-27 18:16:13 +0100471#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
472
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200473#undef ROTL8
474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
Hanno Beckerad049a92017-06-19 16:31:54 +0100477#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
480#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
481#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200482
483#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100484#define AES_RT1(idx) ROTL8(RT0[idx])
485#define AES_RT2(idx) ROTL16(RT0[idx])
486#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200487
488#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100489#define AES_FT1(idx) ROTL8(FT0[idx])
490#define AES_FT2(idx) ROTL16(FT0[idx])
491#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200492
Hanno Becker177d3cf2017-06-07 15:52:48 +0100493#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200494
495#define AES_RT0(idx) RT0[idx]
496#define AES_RT1(idx) RT1[idx]
497#define AES_RT2(idx) RT2[idx]
498#define AES_RT3(idx) RT3[idx]
499
500#define AES_FT0(idx) FT0[idx]
501#define AES_FT1(idx) FT1[idx]
502#define AES_FT2(idx) FT2[idx]
503#define AES_FT3(idx) FT3[idx]
504
Hanno Becker177d3cf2017-06-07 15:52:48 +0100505#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200508{
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200510}
511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200513{
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200515 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200519}
520
Jaeden Amero9366feb2018-05-29 18:55:17 +0100521#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100522void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100523{
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 mbedtls_aes_init(&ctx->crypt);
525 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100526}
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100529{
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100531 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 }
Simon Butcher5201e412018-12-06 17:40:14 +0000533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 mbedtls_aes_free(&ctx->crypt);
535 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100536}
537#endif /* MBEDTLS_CIPHER_MODE_XTS */
538
Gilles Peskine0de8f852023-03-16 17:14:59 +0100539/* Some implementations need the round keys to be aligned.
540 * Return an offset to be added to buf, such that (buf + offset) is
541 * correctly aligned.
542 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
543 * i.e. an offset of 1 means 4 bytes and so on.
544 */
545#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100546 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100547#define MAY_NEED_TO_ALIGN
548#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100549
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100550#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
551 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100552static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
553{
554#if defined(MAY_NEED_TO_ALIGN)
555 int align_16_bytes = 0;
556
557#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
558 if (aes_padlock_ace == -1) {
559 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
560 }
561 if (aes_padlock_ace) {
562 align_16_bytes = 1;
563 }
564#endif
565
Gilles Peskine9c682e72023-03-16 17:21:33 +0100566#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100567 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
568 align_16_bytes = 1;
569 }
570#endif
571
572 if (align_16_bytes) {
573 /* These implementations needs 16-byte alignment
574 * for the round key array. */
575 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
576 if (delta == 0) {
577 return 0;
578 } else {
579 return 4 - delta; // 16 bytes = 4 uint32_t
580 }
581 }
582#else /* MAY_NEED_TO_ALIGN */
583 (void) buf;
584#endif /* MAY_NEED_TO_ALIGN */
585
586 return 0;
587}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100588#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
589 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100590
Paul Bakker5121ce52009-01-03 21:22:43 +0000591/*
592 * AES key schedule (encryption)
593 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200594#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100595int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
596 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000597{
Paul Bakker23986e52011-04-24 08:57:21 +0000598 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000599 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800603#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000604 case 192: ctx->nr = 12; break;
605 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800606#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
609
Simon Butcher5201e412018-12-06 17:40:14 +0000610#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000612 aes_gen_tables();
613 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000614 }
615#endif
616
Gilles Peskine0de8f852023-03-16 17:14:59 +0100617 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100618 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100620#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
622 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
623 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100624#endif
625
Jerry Yu3f2fb712023-01-10 17:05:42 +0800626#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
627 if (mbedtls_aesce_has_support()) {
628 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
629 }
630#endif
631
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 for (i = 0; i < (keybits >> 5); i++) {
633 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 case 10:
638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
642 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
643 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
644 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000645
646 RK[5] = RK[1] ^ RK[4];
647 RK[6] = RK[2] ^ RK[5];
648 RK[7] = RK[3] ^ RK[6];
649 }
650 break;
651
Arto Kinnunen732ca322023-04-14 14:26:10 +0800652#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 case 12:
654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000656 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
658 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
659 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
660 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662 RK[7] = RK[1] ^ RK[6];
663 RK[8] = RK[2] ^ RK[7];
664 RK[9] = RK[3] ^ RK[8];
665 RK[10] = RK[4] ^ RK[9];
666 RK[11] = RK[5] ^ RK[10];
667 }
668 break;
669
670 case 14:
671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
675 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
676 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
677 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
679 RK[9] = RK[1] ^ RK[8];
680 RK[10] = RK[2] ^ RK[9];
681 RK[11] = RK[3] ^ RK[10];
682
683 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
685 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
687 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
689 RK[13] = RK[5] ^ RK[12];
690 RK[14] = RK[6] ^ RK[13];
691 RK[15] = RK[7] ^ RK[14];
692 }
693 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800694#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000698}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200699#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701/*
702 * AES key schedule (decryption)
703 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200704#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100705int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
706 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000707{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200708 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000710 uint32_t *RK;
711 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000714
Gilles Peskine0de8f852023-03-16 17:14:59 +0100715 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100716 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200718 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200720 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000722
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200723 ctx->nr = cty.nr;
724
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100725#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
727 mbedtls_aesni_inverse_key((unsigned char *) RK,
728 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200729 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100730 }
731#endif
732
Jerry Yue096da12023-01-10 17:07:01 +0800733#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
734 if (mbedtls_aesce_has_support()) {
735 mbedtls_aesce_inverse_key(
736 (unsigned char *) RK,
737 (const unsigned char *) (cty.buf + cty.rk_offset),
738 ctx->nr);
739 goto exit;
740 }
741#endif
742
Werner Lewisdd76ef32022-05-30 12:00:21 +0100743 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000744
745 *RK++ = *SK++;
746 *RK++ = *SK++;
747 *RK++ = *SK++;
748 *RK++ = *SK++;
749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
751 for (j = 0; j < 4; j++, SK++) {
752 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
753 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
754 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
755 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000756 }
757 }
758
759 *RK++ = *SK++;
760 *RK++ = *SK++;
761 *RK++ = *SK++;
762 *RK++ = *SK++;
763
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200764exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000768}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100769#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100770
771#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100772static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
773 unsigned int keybits,
774 const unsigned char **key1,
775 unsigned int *key1bits,
776 const unsigned char **key2,
777 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100778{
779 const unsigned int half_keybits = keybits / 2;
780 const unsigned int half_keybytes = half_keybits / 8;
781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100783 case 256: break;
784 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100786 }
787
788 *key1bits = half_keybits;
789 *key2bits = half_keybits;
790 *key1 = &key[0];
791 *key2 = &key[half_keybytes];
792
793 return 0;
794}
795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
797 const unsigned char *key,
798 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100799{
Janos Follath24eed8d2019-11-22 13:21:35 +0000800 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100801 const unsigned char *key1, *key2;
802 unsigned int key1bits, key2bits;
803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
805 &key2, &key2bits);
806 if (ret != 0) {
807 return ret;
808 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100809
810 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
812 if (ret != 0) {
813 return ret;
814 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100815
816 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818}
819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
821 const unsigned char *key,
822 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100823{
Janos Follath24eed8d2019-11-22 13:21:35 +0000824 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100825 const unsigned char *key1, *key2;
826 unsigned int key1bits, key2bits;
827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
829 &key2, &key2bits);
830 if (ret != 0) {
831 return ret;
832 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100833
834 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
836 if (ret != 0) {
837 return ret;
838 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100839
840 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100842}
843#endif /* MBEDTLS_CIPHER_MODE_XTS */
844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100846 do \
847 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
849 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
850 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
851 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100852 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
854 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
855 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
856 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100857 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
859 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
860 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
861 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100862 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
864 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
865 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
866 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
867 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100870 do \
871 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
873 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
874 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
875 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100876 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
878 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
879 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
880 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100881 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
883 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
884 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
885 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100886 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
888 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
889 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
890 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
891 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
893/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200894 * AES-ECB block encryption
895 */
896#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100897int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
898 const unsigned char input[16],
899 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900{
901 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100902 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200904 uint32_t X[4];
905 uint32_t Y[4];
906 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
909 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
910 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
911 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
914 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]);
915 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 +0200916 }
917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 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 +0200919
Gilles Peskine5197c662020-08-26 17:03:24 +0200920 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
922 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
923 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
924 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200925
Gilles Peskine5197c662020-08-26 17:03:24 +0200926 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
928 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
929 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
930 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200931
Gilles Peskine5197c662020-08-26 17:03:24 +0200932 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
934 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
935 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
936 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200937
Gilles Peskine5197c662020-08-26 17:03:24 +0200938 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
940 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
941 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
942 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
945 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
946 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
947 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200952}
953#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
954
955/*
956 * AES-ECB block decryption
957 */
958#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100959int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
960 const unsigned char input[16],
961 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962{
963 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100964 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200966 uint32_t X[4];
967 uint32_t Y[4];
968 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
971 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
972 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
973 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
976 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]);
977 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 +0200978 }
979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 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 +0200981
Gilles Peskine5197c662020-08-26 17:03:24 +0200982 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
986 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200987
Gilles Peskine5197c662020-08-26 17:03:24 +0200988 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
992 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200993
Gilles Peskine5197c662020-08-26 17:03:24 +0200994 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
998 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200999
Gilles Peskine5197c662020-08-26 17:03:24 +02001000 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1002 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1003 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1004 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1007 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1008 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1009 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001012
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001014}
1015#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1016
Gilles Peskine0de8f852023-03-16 17:14:59 +01001017#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001018/* VIA Padlock and our intrinsics-based implementation of AESNI require
1019 * the round keys to be aligned on a 16-byte boundary. We take care of this
1020 * before creating them, but the AES context may have moved (this can happen
1021 * if the library is called from a language with managed memory), and in later
1022 * calls it might have a different alignment with respect to 16-byte memory.
1023 * So we may need to realign.
1024 */
1025static void aes_maybe_realign(mbedtls_aes_context *ctx)
1026{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001027 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1028 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001029 memmove(ctx->buf + new_offset, // new address
1030 ctx->buf + ctx->rk_offset, // current address
1031 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1032 ctx->rk_offset = new_offset;
1033 }
1034}
1035#endif
1036
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001037/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 * AES-ECB block encryption/decryption
1039 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001040int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1041 int mode,
1042 const unsigned char input[16],
1043 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001044{
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001046 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001048
Gilles Peskine0de8f852023-03-16 17:14:59 +01001049#if defined(MAY_NEED_TO_ALIGN)
1050 aes_maybe_realign(ctx);
1051#endif
1052
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001053#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1055 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1056 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001057#endif
1058
Jerry Yu2bb3d812023-01-10 17:38:26 +08001059#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1060 if (mbedtls_aesce_has_support()) {
1061 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1062 }
1063#endif
1064
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001067 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001068 }
1069#endif
1070
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 if (mode == MBEDTLS_AES_ENCRYPT) {
1072 return mbedtls_internal_aes_encrypt(ctx, input, output);
1073 } else {
1074 return mbedtls_internal_aes_decrypt(ctx, input, output);
1075 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001076}
1077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001079
Paul Bakker5121ce52009-01-03 21:22:43 +00001080/*
1081 * AES-CBC buffer encryption/decryption
1082 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001083int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1084 int mode,
1085 size_t length,
1086 unsigned char iv[16],
1087 const unsigned char *input,
1088 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001089{
Gilles Peskine7820a572021-07-07 21:08:28 +02001090 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001091 unsigned char temp[16];
1092
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001094 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001096
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 if (length % 16) {
1098 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1099 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001100
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 if (aes_padlock_ace > 0) {
1103 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1104 return 0;
1105 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001106
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001107 // If padlock data misaligned, we just fall back to
1108 // unaccelerated mode
1109 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001110 }
1111#endif
1112
Dave Rodgman906c63c2023-06-14 17:53:51 +01001113 const unsigned char *ivp = iv;
1114
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 if (mode == MBEDTLS_AES_DECRYPT) {
1116 while (length > 0) {
1117 memcpy(temp, input, 16);
1118 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1119 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001120 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001122 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001123 * the result for the next block in CBC, and the cost of transferring that data from
1124 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001125 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001126
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001128
1129 input += 16;
1130 output += 16;
1131 length -= 16;
1132 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 } else {
1134 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001135 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001136
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1138 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001139 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001141 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001142
1143 input += 16;
1144 output += 16;
1145 length -= 16;
1146 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001147 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001149 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001150
Gilles Peskine7820a572021-07-07 21:08:28 +02001151exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001153}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001154#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001155
Aorimn5f778012016-06-09 23:22:58 +02001156#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001157
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001158typedef unsigned char mbedtls_be128[16];
1159
1160/*
1161 * GF(2^128) multiplication function
1162 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001163 * This function multiplies a field element by x in the polynomial field
1164 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001165 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001166 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001167 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001168#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001169MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001170#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001171static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001172 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001173{
1174 uint64_t a, b, ra, rb;
1175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 a = MBEDTLS_GET_UINT64_LE(x, 0);
1177 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001178
Gilles Peskine449bd832023-01-11 14:50:10 +01001179 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1180 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001181
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1183 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001184}
1185
Aorimn5f778012016-06-09 23:22:58 +02001186/*
1187 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001188 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001189 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001190 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001191 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001192#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001193MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001194#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001195int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1196 int mode,
1197 size_t length,
1198 const unsigned char data_unit[16],
1199 const unsigned char *input,
1200 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001201{
Janos Follath24eed8d2019-11-22 13:21:35 +00001202 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001203 size_t blocks = length / 16;
1204 size_t leftover = length % 16;
1205 unsigned char tweak[16];
1206 unsigned char prev_tweak[16];
1207 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001208
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001210 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001211 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001212
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001213 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001215 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001216 }
Aorimn5f778012016-06-09 23:22:58 +02001217
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001218 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001220 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 }
Aorimn5f778012016-06-09 23:22:58 +02001222
Jaeden Amerod82cd862018-04-28 15:02:45 +01001223 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001224 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1225 data_unit, tweak);
1226 if (ret != 0) {
1227 return ret;
1228 }
Aorimn5f778012016-06-09 23:22:58 +02001229
Gilles Peskine449bd832023-01-11 14:50:10 +01001230 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001231 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001232 /* We are on the last block in a decrypt operation that has
1233 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001234 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235 * the leftovers and then update the current tweak for use on this,
1236 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001237 memcpy(prev_tweak, tweak, sizeof(tweak));
1238 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239 }
1240
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001242
Gilles Peskine449bd832023-01-11 14:50:10 +01001243 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1244 if (ret != 0) {
1245 return ret;
1246 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001247
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001249
1250 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252
1253 output += 16;
1254 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001255 }
1256
Gilles Peskine449bd832023-01-11 14:50:10 +01001257 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001258 /* If we are on the leftover bytes in a decrypt operation, we need to
1259 * use the previous tweak for these bytes (as saved in prev_tweak). */
1260 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001261
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 /* We are now on the final part of the data unit, which doesn't divide
1263 * evenly by 16. It's time for ciphertext stealing. */
1264 size_t i;
1265 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001266
Jaeden Amerod82cd862018-04-28 15:02:45 +01001267 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001268 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001270 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001271 }
Aorimn5f778012016-06-09 23:22:58 +02001272
Dave Rodgman069e7f42022-11-24 19:37:26 +00001273 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001275
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276 /* Copy ciphertext bytes from the previous block for input in this
1277 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001279
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1281 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 }
Aorimn5f778012016-06-09 23:22:58 +02001284
Jaeden Amerod82cd862018-04-28 15:02:45 +01001285 /* Write the result back to the previous block, overriding the previous
1286 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001288 }
1289
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001291}
1292#endif /* MBEDTLS_CIPHER_MODE_XTS */
1293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001295/*
1296 * AES-CFB128 buffer encryption/decryption
1297 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001298int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1299 int mode,
1300 size_t length,
1301 size_t *iv_off,
1302 unsigned char iv[16],
1303 const unsigned char *input,
1304 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001305{
Paul Bakker27fdf462011-06-09 13:55:13 +00001306 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001307 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001308 size_t n;
1309
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001311 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001313
1314 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001315
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 if (n > 15) {
1317 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1318 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001319
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 if (mode == MBEDTLS_AES_DECRYPT) {
1321 while (length--) {
1322 if (n == 0) {
1323 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1324 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001325 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001327 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001328
1329 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 iv[n] = (unsigned char) c;
1332
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001334 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 } else {
1336 while (length--) {
1337 if (n == 0) {
1338 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1339 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001340 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001342 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001343
Gilles Peskine449bd832023-01-11 14:50:10 +01001344 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001345
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001347 }
1348 }
1349
1350 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001351 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001352
Gilles Peskine7820a572021-07-07 21:08:28 +02001353exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001354 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001355}
Paul Bakker556efba2014-01-24 15:38:12 +01001356
1357/*
1358 * AES-CFB8 buffer encryption/decryption
1359 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001360int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1361 int mode,
1362 size_t length,
1363 unsigned char iv[16],
1364 const unsigned char *input,
1365 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001366{
Gilles Peskine7820a572021-07-07 21:08:28 +02001367 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001368 unsigned char c;
1369 unsigned char ov[17];
1370
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001372 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 }
1374 while (length--) {
1375 memcpy(ov, iv, 16);
1376 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1377 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001378 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 }
Paul Bakker556efba2014-01-24 15:38:12 +01001380
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001382 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 }
Paul Bakker556efba2014-01-24 15:38:12 +01001384
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001386
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001388 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 }
Paul Bakker556efba2014-01-24 15:38:12 +01001390
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001392 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001393 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001394
Gilles Peskine7820a572021-07-07 21:08:28 +02001395exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001397}
Simon Butcher76a5b222018-04-22 22:57:27 +01001398#endif /* MBEDTLS_CIPHER_MODE_CFB */
1399
1400#if defined(MBEDTLS_CIPHER_MODE_OFB)
1401/*
1402 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1403 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001404int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1405 size_t length,
1406 size_t *iv_off,
1407 unsigned char iv[16],
1408 const unsigned char *input,
1409 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001410{
Simon Butcherad4e4932018-04-29 00:43:47 +01001411 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001412 size_t n;
1413
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001414 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001415
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 if (n > 15) {
1417 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1418 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001419
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 while (length--) {
1421 if (n == 0) {
1422 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1423 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001424 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001426 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001427 *output++ = *input++ ^ iv[n];
1428
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001430 }
1431
1432 *iv_off = n;
1433
Simon Butcherad4e4932018-04-29 00:43:47 +01001434exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001435 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001436}
1437#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001439#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001440/*
1441 * AES-CTR buffer encryption/decryption
1442 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001443int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1444 size_t length,
1445 size_t *nc_off,
1446 unsigned char nonce_counter[16],
1447 unsigned char stream_block[16],
1448 const unsigned char *input,
1449 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001450{
Paul Bakker369e14b2012-04-18 14:16:09 +00001451 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001452 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001453 size_t n;
1454
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001455 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001456
Gilles Peskine449bd832023-01-11 14:50:10 +01001457 if (n > 0x0F) {
1458 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1459 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001460
Gilles Peskine449bd832023-01-11 14:50:10 +01001461 while (length--) {
1462 if (n == 0) {
1463 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1464 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001465 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001466 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001467
Gilles Peskine449bd832023-01-11 14:50:10 +01001468 for (i = 16; i > 0; i--) {
1469 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001470 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001471 }
1472 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001473 }
1474 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001475 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001476
Gilles Peskine449bd832023-01-11 14:50:10 +01001477 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001478 }
1479
1480 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001481 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001482
Gilles Peskine7820a572021-07-07 21:08:28 +02001483exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001484 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001485}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001487
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001488#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001489
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001491/*
1492 * AES test vectors from:
1493 *
1494 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1495 */
Yanray Wang62c99912023-05-11 11:06:53 +08001496static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001497{
1498 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1499 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001500#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001501 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1502 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1503 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1504 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001505#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001506};
1507
Yanray Wang62c99912023-05-11 11:06:53 +08001508static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001509{
1510 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1511 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001512#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001513 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1514 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1515 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1516 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001517#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001518};
1519
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001520#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001521static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001522{
1523 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1524 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001525#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001526 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1527 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1528 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1529 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001530#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001531};
1532
Yanray Wang62c99912023-05-11 11:06:53 +08001533static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001534{
1535 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1536 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
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 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1539 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1540 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1541 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001542#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001543};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001544#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001545
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001546#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001547/*
1548 * AES-CFB128 test vectors from:
1549 *
1550 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1551 */
Yanray Wang62c99912023-05-11 11:06:53 +08001552static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001553{
1554 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1555 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001556#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001557 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1558 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1559 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1560 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1561 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1562 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1563 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001564#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001565};
1566
1567static const unsigned char aes_test_cfb128_iv[16] =
1568{
1569 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1570 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1571};
1572
1573static const unsigned char aes_test_cfb128_pt[64] =
1574{
1575 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1576 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1577 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1578 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1579 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1580 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1581 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1582 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1583};
1584
Yanray Wang62c99912023-05-11 11:06:53 +08001585static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001586{
1587 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1588 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1589 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1590 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1591 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1592 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1593 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1594 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001595#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001596 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1597 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1598 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1599 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1600 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1601 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1602 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1603 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1604 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1605 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1606 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1607 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1608 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1609 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1610 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1611 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001612#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001613};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001614#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001615
Simon Butcherad4e4932018-04-29 00:43:47 +01001616#if defined(MBEDTLS_CIPHER_MODE_OFB)
1617/*
1618 * AES-OFB test vectors from:
1619 *
Simon Butcher5db13622018-06-04 22:11:25 +01001620 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001621 */
Yanray Wang62c99912023-05-11 11:06:53 +08001622static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001623{
1624 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1625 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001626#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001627 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1628 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1629 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1630 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1631 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1632 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1633 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001634#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001635};
1636
1637static const unsigned char aes_test_ofb_iv[16] =
1638{
1639 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1640 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1641};
1642
1643static const unsigned char aes_test_ofb_pt[64] =
1644{
1645 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1646 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1647 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1648 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1649 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1650 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1651 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1652 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1653};
1654
Yanray Wang62c99912023-05-11 11:06:53 +08001655static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001656{
1657 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1658 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1659 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1660 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1661 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1662 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1663 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1664 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001665#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001666 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1667 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1668 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1669 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1670 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1671 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1672 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1673 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1674 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1675 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1676 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1677 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1678 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1679 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1680 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1681 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001682#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001683};
1684#endif /* MBEDTLS_CIPHER_MODE_OFB */
1685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001686#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001687/*
1688 * AES-CTR test vectors from:
1689 *
1690 * http://www.faqs.org/rfcs/rfc3686.html
1691 */
1692
Yanray Wang62c99912023-05-11 11:06:53 +08001693static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001694{
1695 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1696 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1697 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1698 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1699 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1700 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1701};
1702
Yanray Wang62c99912023-05-11 11:06:53 +08001703static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001704{
1705 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1707 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1708 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1709 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1710 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1711};
1712
Yanray Wang62c99912023-05-11 11:06:53 +08001713static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001714{
1715 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1716 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001717 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1718 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1719 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1720 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1721
1722 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1723 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1724 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1725 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1726 0x20, 0x21, 0x22, 0x23 }
1727};
1728
Yanray Wang62c99912023-05-11 11:06:53 +08001729static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001730{
1731 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1732 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1733 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1734 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1735 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1736 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1737 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1738 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1739 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1740 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1741 0x25, 0xB2, 0x07, 0x2F }
1742};
1743
1744static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001745{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001746#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001747
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001748#if defined(MBEDTLS_CIPHER_MODE_XTS)
1749/*
1750 * AES-XTS test vectors from:
1751 *
1752 * IEEE P1619/D16 Annex B
1753 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1754 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1755 */
1756static const unsigned char aes_test_xts_key[][32] =
1757{
1758 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1761 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1762 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1763 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1764 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1765 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1766 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1767 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1768 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1769 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1770};
1771
1772static const unsigned char aes_test_xts_pt32[][32] =
1773{
1774 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1778 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1779 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1780 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1781 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1782 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1783 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1784 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1785 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1786};
1787
1788static const unsigned char aes_test_xts_ct32[][32] =
1789{
1790 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1791 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1792 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1793 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1794 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1795 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1796 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1797 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1798 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1799 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1800 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1801 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1802};
1803
1804static const unsigned char aes_test_xts_data_unit[][16] =
1805{
Gilles Peskine449bd832023-01-11 14:50:10 +01001806 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1808 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1810 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001812};
1813
1814#endif /* MBEDTLS_CIPHER_MODE_XTS */
1815
Paul Bakker5121ce52009-01-03 21:22:43 +00001816/*
1817 * Checkup routine
1818 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001819int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001820{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001821 int ret = 0, i, j, u, mode;
1822 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 unsigned char key[32];
1824 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001825 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001826#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1827 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001828 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001829#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001830#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001831 unsigned char prv[16];
1832#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001833#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1834 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001835 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001836#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001837#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001838 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001839#endif
1840#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001841 unsigned char nonce_counter[16];
1842 unsigned char stream_block[16];
1843#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001844 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001845
Gilles Peskine449bd832023-01-11 14:50:10 +01001846 memset(key, 0, 32);
1847 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001848
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001849 if (verbose != 0) {
1850#if defined(MBEDTLS_AES_ALT)
1851 mbedtls_printf(" AES note: alternative implementation.\n");
1852#else /* MBEDTLS_AES_ALT */
1853#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1854 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1855 mbedtls_printf(" AES note: using VIA Padlock.\n");
1856 } else
1857#endif
1858#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001859#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001860 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001861#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001862 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001863#else
1864#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1865#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001866 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1867 mbedtls_printf(" AES note: using AESNI.\n");
1868 } else
1869#endif
1870#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1871 if (mbedtls_aesce_has_support()) {
1872 mbedtls_printf(" AES note: using AESCE.\n");
1873 } else
1874#endif
1875 mbedtls_printf(" AES note: built-in implementation.\n");
1876#endif /* MBEDTLS_AES_ALT */
1877 }
1878
Paul Bakker5121ce52009-01-03 21:22:43 +00001879 /*
1880 * ECB mode
1881 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001882 {
1883 static const int num_tests =
1884 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001885
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001886 for (i = 0; i < num_tests << 1; i++) {
1887 u = i >> 1;
1888 keybits = 128 + u * 64;
1889 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001890
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001891 if (verbose != 0) {
1892 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1893 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1894 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001895
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001896 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001897
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001898 if (mode == MBEDTLS_AES_DECRYPT) {
1899 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1900 aes_tests = aes_test_ecb_dec[u];
1901 } else {
1902 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1903 aes_tests = aes_test_ecb_enc[u];
1904 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001905
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001906 /*
1907 * AES-192 is an optional feature that may be unavailable when
1908 * there is an alternative underlying implementation i.e. when
1909 * MBEDTLS_AES_ALT is defined.
1910 */
1911 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1912 mbedtls_printf("skipped\n");
1913 continue;
1914 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001915 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001916 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001917
1918 for (j = 0; j < 10000; j++) {
1919 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1920 if (ret != 0) {
1921 goto exit;
1922 }
1923 }
1924
1925 if (memcmp(buf, aes_tests, 16) != 0) {
1926 ret = 1;
1927 goto exit;
1928 }
1929
1930 if (verbose != 0) {
1931 mbedtls_printf("passed\n");
1932 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001933 }
1934
Gilles Peskine449bd832023-01-11 14:50:10 +01001935 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001936 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001937 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001938 }
1939
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001940#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001941 /*
1942 * CBC mode
1943 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001944 {
1945 static const int num_tests =
1946 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001947
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001948 for (i = 0; i < num_tests << 1; i++) {
1949 u = i >> 1;
1950 keybits = 128 + u * 64;
1951 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001952
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001953 if (verbose != 0) {
1954 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1955 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 }
1957
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001958 memset(iv, 0, 16);
1959 memset(prv, 0, 16);
1960 memset(buf, 0, 16);
1961
1962 if (mode == MBEDTLS_AES_DECRYPT) {
1963 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1964 aes_tests = aes_test_cbc_dec[u];
1965 } else {
1966 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1967 aes_tests = aes_test_cbc_enc[u];
1968 }
1969
1970 /*
1971 * AES-192 is an optional feature that may be unavailable when
1972 * there is an alternative underlying implementation i.e. when
1973 * MBEDTLS_AES_ALT is defined.
1974 */
1975 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1976 mbedtls_printf("skipped\n");
1977 continue;
1978 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001979 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001980 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001981
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001982 for (j = 0; j < 10000; j++) {
1983 if (mode == MBEDTLS_AES_ENCRYPT) {
1984 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001985
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001986 memcpy(tmp, prv, 16);
1987 memcpy(prv, buf, 16);
1988 memcpy(buf, tmp, 16);
1989 }
1990
1991 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1992 if (ret != 0) {
1993 goto exit;
1994 }
1995
1996 }
1997
1998 if (memcmp(buf, aes_tests, 16) != 0) {
1999 ret = 1;
2000 goto exit;
2001 }
2002
2003 if (verbose != 0) {
2004 mbedtls_printf("passed\n");
2005 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002006 }
2007
Gilles Peskine449bd832023-01-11 14:50:10 +01002008 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002009 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002010 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002011 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002013
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002014#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002015 /*
2016 * CFB128 mode
2017 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002018 {
2019 static const int num_tests =
2020 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002021
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002022 for (i = 0; i < num_tests << 1; i++) {
2023 u = i >> 1;
2024 keybits = 128 + u * 64;
2025 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002026
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002027 if (verbose != 0) {
2028 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2029 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2030 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002031
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002032 memcpy(iv, aes_test_cfb128_iv, 16);
2033 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002034
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002035 offset = 0;
2036 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2037 /*
2038 * AES-192 is an optional feature that may be unavailable when
2039 * there is an alternative underlying implementation i.e. when
2040 * MBEDTLS_AES_ALT is defined.
2041 */
2042 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2043 mbedtls_printf("skipped\n");
2044 continue;
2045 } else if (ret != 0) {
2046 goto exit;
2047 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002048
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002049 if (mode == MBEDTLS_AES_DECRYPT) {
2050 memcpy(buf, aes_test_cfb128_ct[u], 64);
2051 aes_tests = aes_test_cfb128_pt;
2052 } else {
2053 memcpy(buf, aes_test_cfb128_pt, 64);
2054 aes_tests = aes_test_cfb128_ct[u];
2055 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002056
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002057 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2058 if (ret != 0) {
2059 goto exit;
2060 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002061
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002062 if (memcmp(buf, aes_tests, 64) != 0) {
2063 ret = 1;
2064 goto exit;
2065 }
2066
2067 if (verbose != 0) {
2068 mbedtls_printf("passed\n");
2069 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002070 }
2071
Gilles Peskine449bd832023-01-11 14:50:10 +01002072 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002073 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002074 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002076#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002077
Simon Butcherad4e4932018-04-29 00:43:47 +01002078#if defined(MBEDTLS_CIPHER_MODE_OFB)
2079 /*
2080 * OFB mode
2081 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002082 {
2083 static const int num_tests =
2084 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002085
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002086 for (i = 0; i < num_tests << 1; i++) {
2087 u = i >> 1;
2088 keybits = 128 + u * 64;
2089 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002090
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002091 if (verbose != 0) {
2092 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2093 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2094 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002095
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 memcpy(iv, aes_test_ofb_iv, 16);
2097 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002098
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002099 offset = 0;
2100 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2101 /*
2102 * AES-192 is an optional feature that may be unavailable when
2103 * there is an alternative underlying implementation i.e. when
2104 * MBEDTLS_AES_ALT is defined.
2105 */
2106 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2107 mbedtls_printf("skipped\n");
2108 continue;
2109 } else if (ret != 0) {
2110 goto exit;
2111 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002112
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002113 if (mode == MBEDTLS_AES_DECRYPT) {
2114 memcpy(buf, aes_test_ofb_ct[u], 64);
2115 aes_tests = aes_test_ofb_pt;
2116 } else {
2117 memcpy(buf, aes_test_ofb_pt, 64);
2118 aes_tests = aes_test_ofb_ct[u];
2119 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002120
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002121 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2122 if (ret != 0) {
2123 goto exit;
2124 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002125
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002126 if (memcmp(buf, aes_tests, 64) != 0) {
2127 ret = 1;
2128 goto exit;
2129 }
2130
2131 if (verbose != 0) {
2132 mbedtls_printf("passed\n");
2133 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002134 }
2135
Gilles Peskine449bd832023-01-11 14:50:10 +01002136 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002137 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002138 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002139 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002140#endif /* MBEDTLS_CIPHER_MODE_OFB */
2141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002142#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002143 /*
2144 * CTR mode
2145 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002146 {
2147 static const int num_tests =
2148 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002149
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002150 for (i = 0; i < num_tests << 1; i++) {
2151 u = i >> 1;
2152 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002153
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002154 if (verbose != 0) {
2155 mbedtls_printf(" AES-CTR-128 (%s): ",
2156 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2157 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002158
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002159 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2160 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002161
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002162 offset = 0;
2163 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2164 goto exit;
2165 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002166
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002167 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002168
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002169 if (mode == MBEDTLS_AES_DECRYPT) {
2170 memcpy(buf, aes_test_ctr_ct[u], len);
2171 aes_tests = aes_test_ctr_pt[u];
2172 } else {
2173 memcpy(buf, aes_test_ctr_pt[u], len);
2174 aes_tests = aes_test_ctr_ct[u];
2175 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002176
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002177 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2178 stream_block, buf, buf);
2179 if (ret != 0) {
2180 goto exit;
2181 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002182
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002183 if (memcmp(buf, aes_tests, len) != 0) {
2184 ret = 1;
2185 goto exit;
2186 }
2187
2188 if (verbose != 0) {
2189 mbedtls_printf("passed\n");
2190 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002191 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002192 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002193
Gilles Peskine449bd832023-01-11 14:50:10 +01002194 if (verbose != 0) {
2195 mbedtls_printf("\n");
2196 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002197#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002198
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002199#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002200 /*
2201 * XTS mode
2202 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002203 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002204 static const int num_tests =
2205 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2206 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002207
Gilles Peskine449bd832023-01-11 14:50:10 +01002208 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002209
Gilles Peskine449bd832023-01-11 14:50:10 +01002210 for (i = 0; i < num_tests << 1; i++) {
2211 const unsigned char *data_unit;
2212 u = i >> 1;
2213 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002214
Gilles Peskine449bd832023-01-11 14:50:10 +01002215 if (verbose != 0) {
2216 mbedtls_printf(" AES-XTS-128 (%s): ",
2217 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2218 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002219
Gilles Peskine449bd832023-01-11 14:50:10 +01002220 memset(key, 0, sizeof(key));
2221 memcpy(key, aes_test_xts_key[u], 32);
2222 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002223
Gilles Peskine449bd832023-01-11 14:50:10 +01002224 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002225
Gilles Peskine449bd832023-01-11 14:50:10 +01002226 if (mode == MBEDTLS_AES_DECRYPT) {
2227 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2228 if (ret != 0) {
2229 goto exit;
2230 }
2231 memcpy(buf, aes_test_xts_ct32[u], len);
2232 aes_tests = aes_test_xts_pt32[u];
2233 } else {
2234 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2235 if (ret != 0) {
2236 goto exit;
2237 }
2238 memcpy(buf, aes_test_xts_pt32[u], len);
2239 aes_tests = aes_test_xts_ct32[u];
2240 }
2241
2242
2243 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2244 buf, buf);
2245 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 }
2248
2249 if (memcmp(buf, aes_tests, len) != 0) {
2250 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002251 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002252 }
2253
2254 if (verbose != 0) {
2255 mbedtls_printf("passed\n");
2256 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002257 }
2258
Gilles Peskine449bd832023-01-11 14:50:10 +01002259 if (verbose != 0) {
2260 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002261 }
2262
Gilles Peskine449bd832023-01-11 14:50:10 +01002263 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002264 }
2265#endif /* MBEDTLS_CIPHER_MODE_XTS */
2266
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002267 ret = 0;
2268
2269exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002270 if (ret != 0 && verbose != 0) {
2271 mbedtls_printf("failed\n");
2272 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002273
Gilles Peskine449bd832023-01-11 14:50:10 +01002274 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002275
Gilles Peskine449bd832023-01-11 14:50:10 +01002276 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002277}
2278
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002279#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002280
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002281#endif /* MBEDTLS_AES_C */