blob: d135485318b9590d1f7ad1bd3525218b1f3e50a1 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
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 Rodgman2fd8c2c2023-06-27 21:03:31 +010095#endif \
96 /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !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
Dave Rodgman160088d2023-06-27 20:41:51 +0100324#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100325
Hanno Becker177d3cf2017-06-07 15:52:48 +0100326#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200327
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 Rodgman2fd8c2c2023-06-27 21:03:31 +0100350#endif \
351 /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || !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 Rodgman15cd28a2023-06-27 18:27:31 +0100366#endif
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{
394 int i, x, y, z;
395 int pow[256];
396 int log[256];
397
398 /*
399 * compute pow and log tables over GF(2^8)
400 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000402 pow[i] = x;
403 log[x] = i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 }
406
407 /*
408 * calculate the round constants
409 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000411 RCON[i] = (uint32_t) x;
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 }
414
415 /*
416 * generate the forward and reverse S-boxes
417 */
418 FSb[0x00] = 0x63;
419 RSb[0x63] = 0x00;
420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000422 x = pow[255 - log[i]];
423
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
425 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
426 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
427 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000428 x ^= y ^ 0x63;
429
430 FSb[i] = (unsigned char) x;
431 RSb[x] = (unsigned char) i;
432 }
433
434 /*
435 * generate the forward and reverse tables
436 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 x = FSb[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 y = MBEDTLS_BYTE_0(XTIME(x));
440 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000441
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 FT0[i] = ((uint32_t) y) ^
443 ((uint32_t) x << 8) ^
444 ((uint32_t) x << 16) ^
445 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
Hanno Beckerad049a92017-06-19 16:31:54 +0100447#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 FT1[i] = ROTL8(FT0[i]);
449 FT2[i] = ROTL8(FT1[i]);
450 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100451#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453 x = RSb[i];
454
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100455#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
457 ((uint32_t) MUL(0x09, x) << 8) ^
458 ((uint32_t) MUL(0x0D, x) << 16) ^
459 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
Hanno Beckerad049a92017-06-19 16:31:54 +0100461#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 RT1[i] = ROTL8(RT0[i]);
463 RT2[i] = ROTL8(RT1[i]);
464 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100465#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100466#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000467 }
468}
469
Dave Rodgman8c753f92023-06-27 18:16:13 +0100470#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
471
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472#undef ROTL8
473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Hanno Beckerad049a92017-06-19 16:31:54 +0100476#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
479#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
480#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200481
482#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100483#define AES_RT1(idx) ROTL8(RT0[idx])
484#define AES_RT2(idx) ROTL16(RT0[idx])
485#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200486
487#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100488#define AES_FT1(idx) ROTL8(FT0[idx])
489#define AES_FT2(idx) ROTL16(FT0[idx])
490#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200491
Hanno Becker177d3cf2017-06-07 15:52:48 +0100492#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200493
494#define AES_RT0(idx) RT0[idx]
495#define AES_RT1(idx) RT1[idx]
496#define AES_RT2(idx) RT2[idx]
497#define AES_RT3(idx) RT3[idx]
498
499#define AES_FT0(idx) FT0[idx]
500#define AES_FT1(idx) FT1[idx]
501#define AES_FT2(idx) FT2[idx]
502#define AES_FT3(idx) FT3[idx]
503
Hanno Becker177d3cf2017-06-07 15:52:48 +0100504#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200505
Gilles Peskine449bd832023-01-11 14:50:10 +0100506void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200507{
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200509}
510
Gilles Peskine449bd832023-01-11 14:50:10 +0100511void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200512{
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200514 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200516
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200518}
519
Jaeden Amero9366feb2018-05-29 18:55:17 +0100520#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100521void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100522{
Gilles Peskine449bd832023-01-11 14:50:10 +0100523 mbedtls_aes_init(&ctx->crypt);
524 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100525}
526
Gilles Peskine449bd832023-01-11 14:50:10 +0100527void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100528{
Gilles Peskine449bd832023-01-11 14:50:10 +0100529 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100530 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 }
Simon Butcher5201e412018-12-06 17:40:14 +0000532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 mbedtls_aes_free(&ctx->crypt);
534 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100535}
536#endif /* MBEDTLS_CIPHER_MODE_XTS */
537
Gilles Peskine0de8f852023-03-16 17:14:59 +0100538/* Some implementations need the round keys to be aligned.
539 * Return an offset to be added to buf, such that (buf + offset) is
540 * correctly aligned.
541 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
542 * i.e. an offset of 1 means 4 bytes and so on.
543 */
544#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100545 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100546#define MAY_NEED_TO_ALIGN
547#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100548
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100549#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
550 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100551static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
552{
553#if defined(MAY_NEED_TO_ALIGN)
554 int align_16_bytes = 0;
555
556#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
557 if (aes_padlock_ace == -1) {
558 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
559 }
560 if (aes_padlock_ace) {
561 align_16_bytes = 1;
562 }
563#endif
564
Gilles Peskine9c682e72023-03-16 17:21:33 +0100565#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100566 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
567 align_16_bytes = 1;
568 }
569#endif
570
571 if (align_16_bytes) {
572 /* These implementations needs 16-byte alignment
573 * for the round key array. */
574 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
575 if (delta == 0) {
576 return 0;
577 } else {
578 return 4 - delta; // 16 bytes = 4 uint32_t
579 }
580 }
581#else /* MAY_NEED_TO_ALIGN */
582 (void) buf;
583#endif /* MAY_NEED_TO_ALIGN */
584
585 return 0;
586}
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100587#endif \
588 /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100589
Paul Bakker5121ce52009-01-03 21:22:43 +0000590/*
591 * AES key schedule (encryption)
592 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200593#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100594int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
595 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000596{
Paul Bakker23986e52011-04-24 08:57:21 +0000597 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000598 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800602#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000603 case 192: ctx->nr = 12; break;
604 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800605#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000607 }
608
Simon Butcher5201e412018-12-06 17:40:14 +0000609#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100610 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000611 aes_gen_tables();
612 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000613 }
614#endif
615
Gilles Peskine0de8f852023-03-16 17:14:59 +0100616 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100617 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100619#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
621 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
622 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100623#endif
624
Jerry Yu3f2fb712023-01-10 17:05:42 +0800625#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
626 if (mbedtls_aesce_has_support()) {
627 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
628 }
629#endif
630
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 for (i = 0; i < (keybits >> 5); i++) {
632 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 }
634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 case 10:
637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000639 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100640 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
641 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
642 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
643 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
645 RK[5] = RK[1] ^ RK[4];
646 RK[6] = RK[2] ^ RK[5];
647 RK[7] = RK[3] ^ RK[6];
648 }
649 break;
650
Arto Kinnunen732ca322023-04-14 14:26:10 +0800651#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000652 case 12:
653
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000655 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
657 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
658 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
659 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
661 RK[7] = RK[1] ^ RK[6];
662 RK[8] = RK[2] ^ RK[7];
663 RK[9] = RK[3] ^ RK[8];
664 RK[10] = RK[4] ^ RK[9];
665 RK[11] = RK[5] ^ RK[10];
666 }
667 break;
668
669 case 14:
670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000672 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
674 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
675 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
676 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678 RK[9] = RK[1] ^ RK[8];
679 RK[10] = RK[2] ^ RK[9];
680 RK[11] = RK[3] ^ RK[10];
681
682 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
684 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
685 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
688 RK[13] = RK[5] ^ RK[12];
689 RK[14] = RK[6] ^ RK[13];
690 RK[15] = RK[7] ^ RK[14];
691 }
692 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800693#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000694 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000695
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000697}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200698#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000699
700/*
701 * AES key schedule (decryption)
702 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200703#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100704int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
705 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000706{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200707 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200708 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000709 uint32_t *RK;
710 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200711
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
Gilles Peskine0de8f852023-03-16 17:14:59 +0100714 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100715 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000716
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200717 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200719 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000721
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200722 ctx->nr = cty.nr;
723
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100724#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
726 mbedtls_aesni_inverse_key((unsigned char *) RK,
727 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200728 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100729 }
730#endif
731
Jerry Yue096da12023-01-10 17:07:01 +0800732#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
733 if (mbedtls_aesce_has_support()) {
734 mbedtls_aesce_inverse_key(
735 (unsigned char *) RK,
736 (const unsigned char *) (cty.buf + cty.rk_offset),
737 ctx->nr);
738 goto exit;
739 }
740#endif
741
Werner Lewisdd76ef32022-05-30 12:00:21 +0100742 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000743
744 *RK++ = *SK++;
745 *RK++ = *SK++;
746 *RK++ = *SK++;
747 *RK++ = *SK++;
748
Gilles Peskine449bd832023-01-11 14:50:10 +0100749 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
750 for (j = 0; j < 4; j++, SK++) {
751 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
752 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
753 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
754 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000755 }
756 }
757
758 *RK++ = *SK++;
759 *RK++ = *SK++;
760 *RK++ = *SK++;
761 *RK++ = *SK++;
762
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200763exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000765
Gilles Peskine449bd832023-01-11 14:50:10 +0100766 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000767}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100768#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100769
770#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100771static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
772 unsigned int keybits,
773 const unsigned char **key1,
774 unsigned int *key1bits,
775 const unsigned char **key2,
776 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100777{
778 const unsigned int half_keybits = keybits / 2;
779 const unsigned int half_keybytes = half_keybits / 8;
780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100782 case 256: break;
783 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100784 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100785 }
786
787 *key1bits = half_keybits;
788 *key2bits = half_keybits;
789 *key1 = &key[0];
790 *key2 = &key[half_keybytes];
791
792 return 0;
793}
794
Gilles Peskine449bd832023-01-11 14:50:10 +0100795int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
796 const unsigned char *key,
797 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100798{
Janos Follath24eed8d2019-11-22 13:21:35 +0000799 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100800 const unsigned char *key1, *key2;
801 unsigned int key1bits, key2bits;
802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
804 &key2, &key2bits);
805 if (ret != 0) {
806 return ret;
807 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808
809 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
811 if (ret != 0) {
812 return ret;
813 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100814
815 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100816 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100817}
818
Gilles Peskine449bd832023-01-11 14:50:10 +0100819int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
820 const unsigned char *key,
821 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100822{
Janos Follath24eed8d2019-11-22 13:21:35 +0000823 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100824 const unsigned char *key1, *key2;
825 unsigned int key1bits, key2bits;
826
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
828 &key2, &key2bits);
829 if (ret != 0) {
830 return ret;
831 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100832
833 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
835 if (ret != 0) {
836 return ret;
837 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100838
839 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100841}
842#endif /* MBEDTLS_CIPHER_MODE_XTS */
843
Gilles Peskine449bd832023-01-11 14:50:10 +0100844#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100845 do \
846 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
848 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
849 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
850 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100851 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
853 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
854 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
855 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100856 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
858 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
859 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
860 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100861 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
863 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
864 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
865 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
866 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000867
Gilles Peskine449bd832023-01-11 14:50:10 +0100868#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100869 do \
870 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100871 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
872 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
873 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
874 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100875 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
877 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
878 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
879 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100880 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
882 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
883 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
884 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100885 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
887 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
888 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
889 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
890 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000891
892/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200893 * AES-ECB block encryption
894 */
895#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100896int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
897 const unsigned char input[16],
898 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200899{
900 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100901 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200903 uint32_t X[4];
904 uint32_t Y[4];
905 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
908 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
909 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
910 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200911
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
913 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]);
914 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 +0200915 }
916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 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 +0200918
Gilles Peskine5197c662020-08-26 17:03:24 +0200919 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
921 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
922 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
923 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200924
Gilles Peskine5197c662020-08-26 17:03:24 +0200925 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
927 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
928 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
929 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930
Gilles Peskine5197c662020-08-26 17:03:24 +0200931 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
933 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
934 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
935 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200936
Gilles Peskine5197c662020-08-26 17:03:24 +0200937 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100938 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
939 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
940 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
941 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200942
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
944 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
945 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
946 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000947
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200951}
952#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
953
954/*
955 * AES-ECB block decryption
956 */
957#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100958int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
959 const unsigned char input[16],
960 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200961{
962 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100963 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200965 uint32_t X[4];
966 uint32_t Y[4];
967 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200968
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
970 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
971 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
972 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
975 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]);
976 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 +0200977 }
978
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 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 +0200980
Gilles Peskine5197c662020-08-26 17:03:24 +0200981 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100982 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986
Gilles Peskine5197c662020-08-26 17:03:24 +0200987 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200992
Gilles Peskine5197c662020-08-26 17:03:24 +0200993 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100994 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
995 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200998
Gilles Peskine5197c662020-08-26 17:03:24 +0200999 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001000 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1001 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1002 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1003 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001004
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1006 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1007 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1008 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001009
Gilles Peskine449bd832023-01-11 14:50:10 +01001010 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001013}
1014#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1015
Gilles Peskine0de8f852023-03-16 17:14:59 +01001016#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001017/* VIA Padlock and our intrinsics-based implementation of AESNI require
1018 * the round keys to be aligned on a 16-byte boundary. We take care of this
1019 * before creating them, but the AES context may have moved (this can happen
1020 * if the library is called from a language with managed memory), and in later
1021 * calls it might have a different alignment with respect to 16-byte memory.
1022 * So we may need to realign.
1023 */
1024static void aes_maybe_realign(mbedtls_aes_context *ctx)
1025{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001026 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1027 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001028 memmove(ctx->buf + new_offset, // new address
1029 ctx->buf + ctx->rk_offset, // current address
1030 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1031 ctx->rk_offset = new_offset;
1032 }
1033}
1034#endif
1035
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001036/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001037 * AES-ECB block encryption/decryption
1038 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001039int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1040 int mode,
1041 const unsigned char input[16],
1042 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001043{
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001045 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001047
Gilles Peskine0de8f852023-03-16 17:14:59 +01001048#if defined(MAY_NEED_TO_ALIGN)
1049 aes_maybe_realign(ctx);
1050#endif
1051
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001052#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1054 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1055 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001056#endif
1057
Jerry Yu2bb3d812023-01-10 17:38:26 +08001058#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1059 if (mbedtls_aesce_has_support()) {
1060 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1061 }
1062#endif
1063
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001066 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001067 }
1068#endif
1069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 if (mode == MBEDTLS_AES_ENCRYPT) {
1071 return mbedtls_internal_aes_encrypt(ctx, input, output);
1072 } else {
1073 return mbedtls_internal_aes_decrypt(ctx, input, output);
1074 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001075}
1076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001078
1079#if defined(__ARM_NEON) && defined(__aarch64__)
Dave Rodgman28a97ac2023-06-14 20:15:15 +01001080/* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
1081 * the result for the next block in CBC, and the cost of transferring that data from
1082 * NEON registers, it is faster to use the following on aarch64.
1083 * For 32-bit arm, NEON should be faster. */
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001084#define CBC_XOR_16(r, a, b) do { \
Dave Rodgman28a97ac2023-06-14 20:15:15 +01001085 mbedtls_put_unaligned_uint64(r, \
1086 mbedtls_get_unaligned_uint64(a) ^ \
1087 mbedtls_get_unaligned_uint64(b)); \
1088 mbedtls_put_unaligned_uint64(r + 8, \
1089 mbedtls_get_unaligned_uint64(a + 8) ^ \
1090 mbedtls_get_unaligned_uint64(b + 8)); \
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001091} while (0)
1092#else
1093#define CBC_XOR_16(r, a, b) mbedtls_xor(r, a, b, 16)
1094#endif
1095
Paul Bakker5121ce52009-01-03 21:22:43 +00001096/*
1097 * AES-CBC buffer encryption/decryption
1098 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001099int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1100 int mode,
1101 size_t length,
1102 unsigned char iv[16],
1103 const unsigned char *input,
1104 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001105{
Gilles Peskine7820a572021-07-07 21:08:28 +02001106 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001107 unsigned char temp[16];
1108
Gilles Peskine449bd832023-01-11 14:50:10 +01001109 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001110 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001111 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001112
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 if (length % 16) {
1114 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1115 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 if (aes_padlock_ace > 0) {
1119 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1120 return 0;
1121 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001122
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001123 // If padlock data misaligned, we just fall back to
1124 // unaccelerated mode
1125 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001126 }
1127#endif
1128
Dave Rodgman906c63c2023-06-14 17:53:51 +01001129 const unsigned char *ivp = iv;
1130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 if (mode == MBEDTLS_AES_DECRYPT) {
1132 while (length > 0) {
1133 memcpy(temp, input, 16);
1134 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1135 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001136 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 }
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001138 CBC_XOR_16(output, output, iv);
Paul Bakker5121ce52009-01-03 21:22:43 +00001139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
1142 input += 16;
1143 output += 16;
1144 length -= 16;
1145 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 } else {
1147 while (length > 0) {
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001148 CBC_XOR_16(output, input, ivp);
Paul Bakker5121ce52009-01-03 21:22:43 +00001149
Gilles Peskine449bd832023-01-11 14:50:10 +01001150 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1151 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001152 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001154 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001155
1156 input += 16;
1157 output += 16;
1158 length -= 16;
1159 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001160 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001161 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001162 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001163
Gilles Peskine7820a572021-07-07 21:08:28 +02001164exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001166}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001167#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001168
Aorimn5f778012016-06-09 23:22:58 +02001169#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001170
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001171typedef unsigned char mbedtls_be128[16];
1172
1173/*
1174 * GF(2^128) multiplication function
1175 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001176 * This function multiplies a field element by x in the polynomial field
1177 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001178 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001179 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001180 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001181static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1182 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001183{
1184 uint64_t a, b, ra, rb;
1185
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 a = MBEDTLS_GET_UINT64_LE(x, 0);
1187 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001188
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1190 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001191
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1193 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001194}
1195
Aorimn5f778012016-06-09 23:22:58 +02001196/*
1197 * AES-XTS buffer encryption/decryption
1198 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001199int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1200 int mode,
1201 size_t length,
1202 const unsigned char data_unit[16],
1203 const unsigned char *input,
1204 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001205{
Janos Follath24eed8d2019-11-22 13:21:35 +00001206 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001207 size_t blocks = length / 16;
1208 size_t leftover = length % 16;
1209 unsigned char tweak[16];
1210 unsigned char prev_tweak[16];
1211 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001212
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001214 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001216
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001217 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001219 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 }
Aorimn5f778012016-06-09 23:22:58 +02001221
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001222 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001224 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 }
Aorimn5f778012016-06-09 23:22:58 +02001226
Jaeden Amerod82cd862018-04-28 15:02:45 +01001227 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1229 data_unit, tweak);
1230 if (ret != 0) {
1231 return ret;
1232 }
Aorimn5f778012016-06-09 23:22:58 +02001233
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001235 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001236 /* We are on the last block in a decrypt operation that has
1237 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001238 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239 * the leftovers and then update the current tweak for use on this,
1240 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 memcpy(prev_tweak, tweak, sizeof(tweak));
1242 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001243 }
1244
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001246
Gilles Peskine449bd832023-01-11 14:50:10 +01001247 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1248 if (ret != 0) {
1249 return ret;
1250 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001251
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253
1254 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256
1257 output += 16;
1258 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001259 }
1260
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 /* If we are on the leftover bytes in a decrypt operation, we need to
1263 * use the previous tweak for these bytes (as saved in prev_tweak). */
1264 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001265
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 /* We are now on the final part of the data unit, which doesn't divide
1267 * evenly by 16. It's time for ciphertext stealing. */
1268 size_t i;
1269 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001270
Jaeden Amerod82cd862018-04-28 15:02:45 +01001271 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001272 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001275 }
Aorimn5f778012016-06-09 23:22:58 +02001276
Dave Rodgman069e7f42022-11-24 19:37:26 +00001277 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001279
Jaeden Amerod82cd862018-04-28 15:02:45 +01001280 /* Copy ciphertext bytes from the previous block for input in this
1281 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001283
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1285 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001286 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 }
Aorimn5f778012016-06-09 23:22:58 +02001288
Jaeden Amerod82cd862018-04-28 15:02:45 +01001289 /* Write the result back to the previous block, overriding the previous
1290 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001292 }
1293
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001295}
1296#endif /* MBEDTLS_CIPHER_MODE_XTS */
1297
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001298#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001299/*
1300 * AES-CFB128 buffer encryption/decryption
1301 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001302int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1303 int mode,
1304 size_t length,
1305 size_t *iv_off,
1306 unsigned char iv[16],
1307 const unsigned char *input,
1308 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001309{
Paul Bakker27fdf462011-06-09 13:55:13 +00001310 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001311 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001312 size_t n;
1313
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001315 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001317
1318 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001319
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 if (n > 15) {
1321 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1322 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001323
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 if (mode == MBEDTLS_AES_DECRYPT) {
1325 while (length--) {
1326 if (n == 0) {
1327 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1328 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001329 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001331 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001332
1333 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001335 iv[n] = (unsigned char) c;
1336
Gilles Peskine449bd832023-01-11 14:50:10 +01001337 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 } else {
1340 while (length--) {
1341 if (n == 0) {
1342 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1343 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001344 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001346 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001347
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001349
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001351 }
1352 }
1353
1354 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001355 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001356
Gilles Peskine7820a572021-07-07 21:08:28 +02001357exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001359}
Paul Bakker556efba2014-01-24 15:38:12 +01001360
1361/*
1362 * AES-CFB8 buffer encryption/decryption
1363 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001364int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1365 int mode,
1366 size_t length,
1367 unsigned char iv[16],
1368 const unsigned char *input,
1369 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001370{
Gilles Peskine7820a572021-07-07 21:08:28 +02001371 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001372 unsigned char c;
1373 unsigned char ov[17];
1374
Gilles Peskine449bd832023-01-11 14:50:10 +01001375 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001376 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 }
1378 while (length--) {
1379 memcpy(ov, iv, 16);
1380 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1381 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001382 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 }
Paul Bakker556efba2014-01-24 15:38:12 +01001384
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001386 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001387 }
Paul Bakker556efba2014-01-24 15:38:12 +01001388
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001390
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001392 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 }
Paul Bakker556efba2014-01-24 15:38:12 +01001394
Gilles Peskine449bd832023-01-11 14:50:10 +01001395 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001396 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001397 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001398
Gilles Peskine7820a572021-07-07 21:08:28 +02001399exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001400 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001401}
Simon Butcher76a5b222018-04-22 22:57:27 +01001402#endif /* MBEDTLS_CIPHER_MODE_CFB */
1403
1404#if defined(MBEDTLS_CIPHER_MODE_OFB)
1405/*
1406 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1407 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001408int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1409 size_t length,
1410 size_t *iv_off,
1411 unsigned char iv[16],
1412 const unsigned char *input,
1413 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001414{
Simon Butcherad4e4932018-04-29 00:43:47 +01001415 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001416 size_t n;
1417
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001418 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001419
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 if (n > 15) {
1421 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1422 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001423
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 while (length--) {
1425 if (n == 0) {
1426 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1427 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001428 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001430 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001431 *output++ = *input++ ^ iv[n];
1432
Gilles Peskine449bd832023-01-11 14:50:10 +01001433 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001434 }
1435
1436 *iv_off = n;
1437
Simon Butcherad4e4932018-04-29 00:43:47 +01001438exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001439 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001440}
1441#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001444/*
1445 * AES-CTR buffer encryption/decryption
1446 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001447int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1448 size_t length,
1449 size_t *nc_off,
1450 unsigned char nonce_counter[16],
1451 unsigned char stream_block[16],
1452 const unsigned char *input,
1453 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001454{
Paul Bakker369e14b2012-04-18 14:16:09 +00001455 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001456 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001457 size_t n;
1458
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001459 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001460
Gilles Peskine449bd832023-01-11 14:50:10 +01001461 if (n > 0x0F) {
1462 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1463 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001464
Gilles Peskine449bd832023-01-11 14:50:10 +01001465 while (length--) {
1466 if (n == 0) {
1467 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1468 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001469 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001470 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001471
Gilles Peskine449bd832023-01-11 14:50:10 +01001472 for (i = 16; i > 0; i--) {
1473 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001474 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001475 }
1476 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477 }
1478 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001479 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001480
Gilles Peskine449bd832023-01-11 14:50:10 +01001481 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001482 }
1483
1484 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001485 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001486
Gilles Peskine7820a572021-07-07 21:08:28 +02001487exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001488 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001492#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001494#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001495/*
1496 * AES test vectors from:
1497 *
1498 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1499 */
Yanray Wang62c99912023-05-11 11:06:53 +08001500static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001501{
1502 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1503 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001504#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001505 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1506 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1507 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1508 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001509#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001510};
1511
Yanray Wang62c99912023-05-11 11:06:53 +08001512static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001513{
1514 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1515 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001516#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001517 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1518 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1519 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1520 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001521#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001522};
1523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001525static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001526{
1527 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1528 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001529#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001530 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1531 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1532 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1533 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001534#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001535};
1536
Yanray Wang62c99912023-05-11 11:06:53 +08001537static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001538{
1539 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1540 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001541#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001542 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1543 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1544 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1545 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001546#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001547};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001548#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001549
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001550#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001551/*
1552 * AES-CFB128 test vectors from:
1553 *
1554 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1555 */
Yanray Wang62c99912023-05-11 11:06:53 +08001556static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001557{
1558 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1559 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001560#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001561 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1562 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1563 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1564 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1565 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1566 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1567 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001568#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001569};
1570
1571static const unsigned char aes_test_cfb128_iv[16] =
1572{
1573 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1574 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1575};
1576
1577static const unsigned char aes_test_cfb128_pt[64] =
1578{
1579 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1580 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1581 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1582 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1583 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1584 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1585 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1586 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1587};
1588
Yanray Wang62c99912023-05-11 11:06:53 +08001589static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001590{
1591 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1592 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1593 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1594 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1595 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1596 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1597 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1598 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001599#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001600 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1601 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1602 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1603 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1604 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1605 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1606 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1607 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1608 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1609 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1610 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1611 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1612 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1613 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1614 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1615 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001616#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001617};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001618#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001619
Simon Butcherad4e4932018-04-29 00:43:47 +01001620#if defined(MBEDTLS_CIPHER_MODE_OFB)
1621/*
1622 * AES-OFB test vectors from:
1623 *
Simon Butcher5db13622018-06-04 22:11:25 +01001624 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001625 */
Yanray Wang62c99912023-05-11 11:06:53 +08001626static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001627{
1628 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1629 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001630#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001631 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1632 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1633 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1634 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1635 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1636 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1637 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001638#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001639};
1640
1641static const unsigned char aes_test_ofb_iv[16] =
1642{
1643 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1644 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1645};
1646
1647static const unsigned char aes_test_ofb_pt[64] =
1648{
1649 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1650 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1651 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1652 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1653 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1654 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1655 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1656 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1657};
1658
Yanray Wang62c99912023-05-11 11:06:53 +08001659static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001660{
1661 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1662 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1663 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1664 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1665 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1666 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1667 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1668 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001669#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001670 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1671 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1672 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1673 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1674 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1675 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1676 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1677 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1678 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1679 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1680 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1681 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1682 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1683 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1684 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1685 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001686#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001687};
1688#endif /* MBEDTLS_CIPHER_MODE_OFB */
1689
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001690#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001691/*
1692 * AES-CTR test vectors from:
1693 *
1694 * http://www.faqs.org/rfcs/rfc3686.html
1695 */
1696
Yanray Wang62c99912023-05-11 11:06:53 +08001697static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001698{
1699 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1700 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1701 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1702 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1703 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1704 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1705};
1706
Yanray Wang62c99912023-05-11 11:06:53 +08001707static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001708{
1709 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1711 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1712 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1713 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1714 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1715};
1716
Yanray Wang62c99912023-05-11 11:06:53 +08001717static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001718{
1719 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1720 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001721 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1722 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1723 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1724 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1725
1726 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1727 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1728 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1729 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1730 0x20, 0x21, 0x22, 0x23 }
1731};
1732
Yanray Wang62c99912023-05-11 11:06:53 +08001733static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001734{
1735 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1736 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1737 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1738 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1739 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1740 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1741 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1742 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1743 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1744 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1745 0x25, 0xB2, 0x07, 0x2F }
1746};
1747
1748static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001749{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001750#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001751
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001752#if defined(MBEDTLS_CIPHER_MODE_XTS)
1753/*
1754 * AES-XTS test vectors from:
1755 *
1756 * IEEE P1619/D16 Annex B
1757 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1758 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1759 */
1760static const unsigned char aes_test_xts_key[][32] =
1761{
1762 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1766 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1767 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1768 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1769 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1770 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1771 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1772 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1773 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1774};
1775
1776static const unsigned char aes_test_xts_pt32[][32] =
1777{
1778 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1787 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1788 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1789 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1790};
1791
1792static const unsigned char aes_test_xts_ct32[][32] =
1793{
1794 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1795 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1796 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1797 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1798 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1799 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1800 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1801 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1802 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1803 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1804 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1805 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1806};
1807
1808static const unsigned char aes_test_xts_data_unit[][16] =
1809{
Gilles Peskine449bd832023-01-11 14:50:10 +01001810 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1812 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1814 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001816};
1817
1818#endif /* MBEDTLS_CIPHER_MODE_XTS */
1819
Paul Bakker5121ce52009-01-03 21:22:43 +00001820/*
1821 * Checkup routine
1822 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001823int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001824{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001825 int ret = 0, i, j, u, mode;
1826 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 unsigned char key[32];
1828 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001829 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001830#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1831 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001832 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001833#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001834#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001835 unsigned char prv[16];
1836#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001837#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1838 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001839 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001840#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001841#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001842 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001843#endif
1844#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001845 unsigned char nonce_counter[16];
1846 unsigned char stream_block[16];
1847#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001848 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001849
Gilles Peskine449bd832023-01-11 14:50:10 +01001850 memset(key, 0, 32);
1851 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001852
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001853 if (verbose != 0) {
1854#if defined(MBEDTLS_AES_ALT)
1855 mbedtls_printf(" AES note: alternative implementation.\n");
1856#else /* MBEDTLS_AES_ALT */
1857#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1858 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1859 mbedtls_printf(" AES note: using VIA Padlock.\n");
1860 } else
1861#endif
1862#if defined(MBEDTLS_AESNI_HAVE_CODE)
1863 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1864 mbedtls_printf(" AES note: using AESNI.\n");
1865 } else
1866#endif
1867#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1868 if (mbedtls_aesce_has_support()) {
1869 mbedtls_printf(" AES note: using AESCE.\n");
1870 } else
1871#endif
1872 mbedtls_printf(" AES note: built-in implementation.\n");
1873#endif /* MBEDTLS_AES_ALT */
1874 }
1875
Paul Bakker5121ce52009-01-03 21:22:43 +00001876 /*
1877 * ECB mode
1878 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001879 {
1880 static const int num_tests =
1881 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001882
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001883 for (i = 0; i < num_tests << 1; i++) {
1884 u = i >> 1;
1885 keybits = 128 + u * 64;
1886 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001887
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001888 if (verbose != 0) {
1889 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1890 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1891 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001892
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001893 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001894
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001895 if (mode == MBEDTLS_AES_DECRYPT) {
1896 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1897 aes_tests = aes_test_ecb_dec[u];
1898 } else {
1899 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1900 aes_tests = aes_test_ecb_enc[u];
1901 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001902
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001903 /*
1904 * AES-192 is an optional feature that may be unavailable when
1905 * there is an alternative underlying implementation i.e. when
1906 * MBEDTLS_AES_ALT is defined.
1907 */
1908 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1909 mbedtls_printf("skipped\n");
1910 continue;
1911 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001912 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001913 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001914
1915 for (j = 0; j < 10000; j++) {
1916 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1917 if (ret != 0) {
1918 goto exit;
1919 }
1920 }
1921
1922 if (memcmp(buf, aes_tests, 16) != 0) {
1923 ret = 1;
1924 goto exit;
1925 }
1926
1927 if (verbose != 0) {
1928 mbedtls_printf("passed\n");
1929 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001930 }
1931
Gilles Peskine449bd832023-01-11 14:50:10 +01001932 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001933 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001934 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001935 }
1936
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001937#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001938 /*
1939 * CBC mode
1940 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001941 {
1942 static const int num_tests =
1943 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001944
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001945 for (i = 0; i < num_tests << 1; i++) {
1946 u = i >> 1;
1947 keybits = 128 + u * 64;
1948 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001949
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001950 if (verbose != 0) {
1951 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1952 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001953 }
1954
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001955 memset(iv, 0, 16);
1956 memset(prv, 0, 16);
1957 memset(buf, 0, 16);
1958
1959 if (mode == MBEDTLS_AES_DECRYPT) {
1960 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1961 aes_tests = aes_test_cbc_dec[u];
1962 } else {
1963 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1964 aes_tests = aes_test_cbc_enc[u];
1965 }
1966
1967 /*
1968 * AES-192 is an optional feature that may be unavailable when
1969 * there is an alternative underlying implementation i.e. when
1970 * MBEDTLS_AES_ALT is defined.
1971 */
1972 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1973 mbedtls_printf("skipped\n");
1974 continue;
1975 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001976 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001977 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001978
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001979 for (j = 0; j < 10000; j++) {
1980 if (mode == MBEDTLS_AES_ENCRYPT) {
1981 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001982
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001983 memcpy(tmp, prv, 16);
1984 memcpy(prv, buf, 16);
1985 memcpy(buf, tmp, 16);
1986 }
1987
1988 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1989 if (ret != 0) {
1990 goto exit;
1991 }
1992
1993 }
1994
1995 if (memcmp(buf, aes_tests, 16) != 0) {
1996 ret = 1;
1997 goto exit;
1998 }
1999
2000 if (verbose != 0) {
2001 mbedtls_printf("passed\n");
2002 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002003 }
2004
Gilles Peskine449bd832023-01-11 14:50:10 +01002005 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002006 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002007 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002008 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002009#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002010
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002011#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002012 /*
2013 * CFB128 mode
2014 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002015 {
2016 static const int num_tests =
2017 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002018
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002019 for (i = 0; i < num_tests << 1; i++) {
2020 u = i >> 1;
2021 keybits = 128 + u * 64;
2022 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002023
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002024 if (verbose != 0) {
2025 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2026 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2027 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002028
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002029 memcpy(iv, aes_test_cfb128_iv, 16);
2030 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002031
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002032 offset = 0;
2033 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2034 /*
2035 * AES-192 is an optional feature that may be unavailable when
2036 * there is an alternative underlying implementation i.e. when
2037 * MBEDTLS_AES_ALT is defined.
2038 */
2039 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2040 mbedtls_printf("skipped\n");
2041 continue;
2042 } else if (ret != 0) {
2043 goto exit;
2044 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002045
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002046 if (mode == MBEDTLS_AES_DECRYPT) {
2047 memcpy(buf, aes_test_cfb128_ct[u], 64);
2048 aes_tests = aes_test_cfb128_pt;
2049 } else {
2050 memcpy(buf, aes_test_cfb128_pt, 64);
2051 aes_tests = aes_test_cfb128_ct[u];
2052 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002053
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002054 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2055 if (ret != 0) {
2056 goto exit;
2057 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002058
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002059 if (memcmp(buf, aes_tests, 64) != 0) {
2060 ret = 1;
2061 goto exit;
2062 }
2063
2064 if (verbose != 0) {
2065 mbedtls_printf("passed\n");
2066 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002067 }
2068
Gilles Peskine449bd832023-01-11 14:50:10 +01002069 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002070 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002071 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002072 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002073#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002074
Simon Butcherad4e4932018-04-29 00:43:47 +01002075#if defined(MBEDTLS_CIPHER_MODE_OFB)
2076 /*
2077 * OFB mode
2078 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002079 {
2080 static const int num_tests =
2081 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002082
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002083 for (i = 0; i < num_tests << 1; i++) {
2084 u = i >> 1;
2085 keybits = 128 + u * 64;
2086 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002087
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002088 if (verbose != 0) {
2089 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2090 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2091 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002092
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002093 memcpy(iv, aes_test_ofb_iv, 16);
2094 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002095
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 offset = 0;
2097 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2098 /*
2099 * AES-192 is an optional feature that may be unavailable when
2100 * there is an alternative underlying implementation i.e. when
2101 * MBEDTLS_AES_ALT is defined.
2102 */
2103 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2104 mbedtls_printf("skipped\n");
2105 continue;
2106 } else if (ret != 0) {
2107 goto exit;
2108 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002109
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002110 if (mode == MBEDTLS_AES_DECRYPT) {
2111 memcpy(buf, aes_test_ofb_ct[u], 64);
2112 aes_tests = aes_test_ofb_pt;
2113 } else {
2114 memcpy(buf, aes_test_ofb_pt, 64);
2115 aes_tests = aes_test_ofb_ct[u];
2116 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002117
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002118 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2119 if (ret != 0) {
2120 goto exit;
2121 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002122
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002123 if (memcmp(buf, aes_tests, 64) != 0) {
2124 ret = 1;
2125 goto exit;
2126 }
2127
2128 if (verbose != 0) {
2129 mbedtls_printf("passed\n");
2130 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002131 }
2132
Gilles Peskine449bd832023-01-11 14:50:10 +01002133 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002134 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002135 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002136 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002137#endif /* MBEDTLS_CIPHER_MODE_OFB */
2138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002139#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002140 /*
2141 * CTR mode
2142 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002143 {
2144 static const int num_tests =
2145 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002146
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002147 for (i = 0; i < num_tests << 1; i++) {
2148 u = i >> 1;
2149 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002150
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002151 if (verbose != 0) {
2152 mbedtls_printf(" AES-CTR-128 (%s): ",
2153 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2154 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002155
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002156 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2157 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002158
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002159 offset = 0;
2160 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2161 goto exit;
2162 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002163
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002164 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002165
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002166 if (mode == MBEDTLS_AES_DECRYPT) {
2167 memcpy(buf, aes_test_ctr_ct[u], len);
2168 aes_tests = aes_test_ctr_pt[u];
2169 } else {
2170 memcpy(buf, aes_test_ctr_pt[u], len);
2171 aes_tests = aes_test_ctr_ct[u];
2172 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002173
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002174 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2175 stream_block, buf, buf);
2176 if (ret != 0) {
2177 goto exit;
2178 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002179
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002180 if (memcmp(buf, aes_tests, len) != 0) {
2181 ret = 1;
2182 goto exit;
2183 }
2184
2185 if (verbose != 0) {
2186 mbedtls_printf("passed\n");
2187 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002188 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002189 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002190
Gilles Peskine449bd832023-01-11 14:50:10 +01002191 if (verbose != 0) {
2192 mbedtls_printf("\n");
2193 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002194#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002195
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002196#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002197 /*
2198 * XTS mode
2199 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002200 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002201 static const int num_tests =
2202 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2203 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002204
Gilles Peskine449bd832023-01-11 14:50:10 +01002205 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002206
Gilles Peskine449bd832023-01-11 14:50:10 +01002207 for (i = 0; i < num_tests << 1; i++) {
2208 const unsigned char *data_unit;
2209 u = i >> 1;
2210 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002211
Gilles Peskine449bd832023-01-11 14:50:10 +01002212 if (verbose != 0) {
2213 mbedtls_printf(" AES-XTS-128 (%s): ",
2214 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2215 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002216
Gilles Peskine449bd832023-01-11 14:50:10 +01002217 memset(key, 0, sizeof(key));
2218 memcpy(key, aes_test_xts_key[u], 32);
2219 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002220
Gilles Peskine449bd832023-01-11 14:50:10 +01002221 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002222
Gilles Peskine449bd832023-01-11 14:50:10 +01002223 if (mode == MBEDTLS_AES_DECRYPT) {
2224 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2225 if (ret != 0) {
2226 goto exit;
2227 }
2228 memcpy(buf, aes_test_xts_ct32[u], len);
2229 aes_tests = aes_test_xts_pt32[u];
2230 } else {
2231 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2232 if (ret != 0) {
2233 goto exit;
2234 }
2235 memcpy(buf, aes_test_xts_pt32[u], len);
2236 aes_tests = aes_test_xts_ct32[u];
2237 }
2238
2239
2240 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2241 buf, buf);
2242 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002243 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002244 }
2245
2246 if (memcmp(buf, aes_tests, len) != 0) {
2247 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002248 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002249 }
2250
2251 if (verbose != 0) {
2252 mbedtls_printf("passed\n");
2253 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002254 }
2255
Gilles Peskine449bd832023-01-11 14:50:10 +01002256 if (verbose != 0) {
2257 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002258 }
2259
Gilles Peskine449bd832023-01-11 14:50:10 +01002260 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002261 }
2262#endif /* MBEDTLS_CIPHER_MODE_XTS */
2263
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002264 ret = 0;
2265
2266exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002267 if (ret != 0 && verbose != 0) {
2268 mbedtls_printf("failed\n");
2269 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002270
Gilles Peskine449bd832023-01-11 14:50:10 +01002271 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002272
Gilles Peskine449bd832023-01-11 14:50:10 +01002273 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002274}
2275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002276#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002277
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002278#endif /* MBEDTLS_AES_C */