blob: d7e4a7ce1b9a361d10dc6f9066671f4a47ef4934 [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000042
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020046
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010047/* Parameter validation macros based on platform_util.h */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010048#define AES_VALIDATE_RET(cond) \
49 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_AES_BAD_INPUT_DATA)
50#define AES_VALIDATE(cond) \
51 MBEDTLS_INTERNAL_VALIDATE(cond)
Manuel Pégourié-Gonnard0e9cddb2018-12-10 16:37:51 +010052
Gilles Peskine30c356c2023-03-16 14:58:46 +010053#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000054static int aes_padlock_ace = -1;
55#endif
56
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020057#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000058/*
59 * Forward S-box
60 */
61static const unsigned char FSb[256] =
62{
63 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
64 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
65 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
66 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
67 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
68 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
69 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
70 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
71 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
72 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
73 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
74 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
75 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
76 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
77 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
78 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
79 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
80 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
81 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
82 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
83 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
84 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
85 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
86 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
87 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
88 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
89 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
90 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
91 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
92 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
93 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
94 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
95};
96
97/*
98 * Forward tables
99 */
100#define FT \
101\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100102 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
103 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
104 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
105 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
106 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
107 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
108 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
109 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
110 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
111 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
112 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
113 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
114 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
115 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
116 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
117 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
118 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
119 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
120 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
121 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
122 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
123 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
124 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
125 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
126 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
127 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
128 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
129 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
130 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
131 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
132 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
133 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
134 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
135 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
136 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
137 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
138 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
139 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
140 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
141 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
142 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
143 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
144 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
145 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
146 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
147 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
148 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
149 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
150 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
151 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
152 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
153 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
154 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
155 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
156 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
157 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
158 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
159 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
160 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
161 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
162 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
163 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
164 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
165 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 +0000166
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100167#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000168static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000169#undef V
170
Hanno Beckerad049a92017-06-19 16:31:54 +0100171#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200172
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100173#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000174static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000175#undef V
176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100177#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000178static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000179#undef V
180
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100181#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000182static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000183#undef V
184
Hanno Becker177d3cf2017-06-07 15:52:48 +0100185#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200186
Paul Bakker5121ce52009-01-03 21:22:43 +0000187#undef FT
188
189/*
190 * Reverse S-box
191 */
192static const unsigned char RSb[256] =
193{
194 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
195 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
196 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
197 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
198 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
199 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
200 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
201 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
202 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
203 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
204 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
205 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
206 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
207 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
208 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
209 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
210 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
211 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
212 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
213 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
214 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
215 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
216 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
217 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
218 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
219 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
220 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
221 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
222 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
223 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
224 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
225 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
226};
227
228/*
229 * Reverse tables
230 */
231#define RT \
232\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100233 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
234 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
235 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
236 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
237 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
238 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
239 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
240 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
241 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
242 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
243 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
244 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
245 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
246 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
247 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
248 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
249 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
250 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
251 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
252 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
253 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
254 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
255 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
256 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
257 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
258 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
259 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
260 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
261 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
262 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
263 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
264 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
265 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
266 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
267 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
268 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
269 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
270 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
271 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
272 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
273 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
274 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
275 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
276 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
277 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
278 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
279 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
280 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
281 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
282 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
283 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
284 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
285 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
286 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
287 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
288 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
289 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
290 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
291 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
292 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
293 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
294 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
295 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
296 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 +0000297
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100298#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000299static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000300#undef V
301
Hanno Beckerad049a92017-06-19 16:31:54 +0100302#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200303
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100304#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000305static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000306#undef V
307
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100308#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000309static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000310#undef V
311
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100312#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000313static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000314#undef V
315
Hanno Becker177d3cf2017-06-07 15:52:48 +0100316#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200317
Paul Bakker5121ce52009-01-03 21:22:43 +0000318#undef RT
319
320/*
321 * Round constants
322 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000323static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000324{
325 0x00000001, 0x00000002, 0x00000004, 0x00000008,
326 0x00000010, 0x00000020, 0x00000040, 0x00000080,
327 0x0000001B, 0x00000036
328};
329
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000331
332/*
333 * Forward S-box & tables
334 */
335static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200336static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100337#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200338static uint32_t FT1[256];
339static uint32_t FT2[256];
340static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100341#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000342
343/*
344 * Reverse S-box & tables
345 */
346static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100348#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000349static uint32_t RT1[256];
350static uint32_t RT2[256];
351static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100352#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
354/*
355 * Round constants
356 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000357static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000358
359/*
360 * Tables generation code
361 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
363#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
364#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
366static int aes_init_done = 0;
367
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100368static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000369{
370 int i, x, y, z;
371 int pow[256];
372 int log[256];
373
374 /*
375 * compute pow and log tables over GF(2^8)
376 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100377 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 pow[i] = x;
379 log[x] = i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100380 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000381 }
382
383 /*
384 * calculate the round constants
385 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100386 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000387 RCON[i] = (uint32_t) x;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100388 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000389 }
390
391 /*
392 * generate the forward and reverse S-boxes
393 */
394 FSb[0x00] = 0x63;
395 RSb[0x63] = 0x00;
396
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100397 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000398 x = pow[255 - log[i]];
399
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
401 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
402 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
403 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000404 x ^= y ^ 0x63;
405
406 FSb[i] = (unsigned char) x;
407 RSb[x] = (unsigned char) i;
408 }
409
410 /*
411 * generate the forward and reverse tables
412 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100413 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 x = FSb[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100415 y = MBEDTLS_BYTE_0(XTIME(x));
416 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100418 FT0[i] = ((uint32_t) y) ^
419 ((uint32_t) x << 8) ^
420 ((uint32_t) x << 16) ^
421 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Hanno Beckerad049a92017-06-19 16:31:54 +0100423#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100424 FT1[i] = ROTL8(FT0[i]);
425 FT2[i] = ROTL8(FT1[i]);
426 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100427#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
429 x = RSb[i];
430
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
432 ((uint32_t) MUL(0x09, x) << 8) ^
433 ((uint32_t) MUL(0x0D, x) << 16) ^
434 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
Hanno Beckerad049a92017-06-19 16:31:54 +0100436#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100437 RT1[i] = ROTL8(RT0[i]);
438 RT2[i] = ROTL8(RT1[i]);
439 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100440#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 }
442}
443
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200444#undef ROTL8
445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Hanno Beckerad049a92017-06-19 16:31:54 +0100448#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200449
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100450#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
451#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
452#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200453
454#define AES_RT0(idx) RT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100455#define AES_RT1(idx) ROTL8(RT0[idx])
456#define AES_RT2(idx) ROTL16(RT0[idx])
457#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200458
459#define AES_FT0(idx) FT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100460#define AES_FT1(idx) ROTL8(FT0[idx])
461#define AES_FT2(idx) ROTL16(FT0[idx])
462#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200463
Hanno Becker177d3cf2017-06-07 15:52:48 +0100464#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200465
466#define AES_RT0(idx) RT0[idx]
467#define AES_RT1(idx) RT1[idx]
468#define AES_RT2(idx) RT2[idx]
469#define AES_RT3(idx) RT3[idx]
470
471#define AES_FT0(idx) FT0[idx]
472#define AES_FT1(idx) FT1[idx]
473#define AES_FT2(idx) FT2[idx]
474#define AES_FT3(idx) FT3[idx]
475
Hanno Becker177d3cf2017-06-07 15:52:48 +0100476#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200477
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100478void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200479{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100480 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000481
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100482 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200483}
484
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100485void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200486{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200488 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100489 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200490
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100491 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200492}
493
Jaeden Amero9366feb2018-05-29 18:55:17 +0100494#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100495void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100496{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000498
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100499 mbedtls_aes_init(&ctx->crypt);
500 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100501}
502
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100503void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100504{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100505 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100506 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100507 }
Simon Butcher5201e412018-12-06 17:40:14 +0000508
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100509 mbedtls_aes_free(&ctx->crypt);
510 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100511}
512#endif /* MBEDTLS_CIPHER_MODE_XTS */
513
Gilles Peskineb71d4022023-03-16 17:14:59 +0100514/* Some implementations need the round keys to be aligned.
515 * Return an offset to be added to buf, such that (buf + offset) is
516 * correctly aligned.
517 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
518 * i.e. an offset of 1 means 4 bytes and so on.
519 */
520#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine6dec5412023-03-16 17:21:33 +0100521 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100522#define MAY_NEED_TO_ALIGN
523#endif
524static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
525{
526#if defined(MAY_NEED_TO_ALIGN)
527 int align_16_bytes = 0;
528
529#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
530 if (aes_padlock_ace == -1) {
531 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
532 }
533 if (aes_padlock_ace) {
534 align_16_bytes = 1;
535 }
536#endif
537
Gilles Peskine6dec5412023-03-16 17:21:33 +0100538#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskineb71d4022023-03-16 17:14:59 +0100539 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
540 align_16_bytes = 1;
541 }
542#endif
543
544 if (align_16_bytes) {
545 /* These implementations needs 16-byte alignment
546 * for the round key array. */
547 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
548 if (delta == 0) {
549 return 0;
550 } else {
551 return 4 - delta; // 16 bytes = 4 uint32_t
552 }
553 }
554#else /* MAY_NEED_TO_ALIGN */
555 (void) buf;
556#endif /* MAY_NEED_TO_ALIGN */
557
558 return 0;
559}
560
Paul Bakker5121ce52009-01-03 21:22:43 +0000561/*
562 * AES key schedule (encryption)
563 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200564#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100565int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
566 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000567{
Paul Bakker23986e52011-04-24 08:57:21 +0000568 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000569 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571 AES_VALIDATE_RET(ctx != NULL);
572 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100574 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000575 case 128: ctx->nr = 10; break;
576 case 192: ctx->nr = 12; break;
577 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100578 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000579 }
580
Simon Butcher5201e412018-12-06 17:40:14 +0000581#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100582 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000583 aes_gen_tables();
584 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000585 }
586#endif
587
Gilles Peskineb71d4022023-03-16 17:14:59 +0100588 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000589
Gilles Peskine5511a342023-03-10 22:29:32 +0100590#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100591 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
592 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
593 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100594#endif
595
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100596 for (i = 0; i < (keybits >> 5); i++) {
597 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000598 }
599
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100600 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 case 10:
602
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000604 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100605 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
606 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
607 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
608 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
610 RK[5] = RK[1] ^ RK[4];
611 RK[6] = RK[2] ^ RK[5];
612 RK[7] = RK[3] ^ RK[6];
613 }
614 break;
615
616 case 12:
617
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100618 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000619 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100620 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
621 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
622 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
623 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000624
625 RK[7] = RK[1] ^ RK[6];
626 RK[8] = RK[2] ^ RK[7];
627 RK[9] = RK[3] ^ RK[8];
628 RK[10] = RK[4] ^ RK[9];
629 RK[11] = RK[5] ^ RK[10];
630 }
631 break;
632
633 case 14:
634
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100635 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100637 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
638 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
639 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
640 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
642 RK[9] = RK[1] ^ RK[8];
643 RK[10] = RK[2] ^ RK[9];
644 RK[11] = RK[3] ^ RK[10];
645
646 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100647 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
648 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
649 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
650 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
652 RK[13] = RK[5] ^ RK[12];
653 RK[14] = RK[6] ^ RK[13];
654 RK[15] = RK[7] ^ RK[14];
655 }
656 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000658
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100659 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000660}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200661#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
663/*
664 * AES key schedule (decryption)
665 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200666#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100667int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
668 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000669{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200670 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000672 uint32_t *RK;
673 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200674
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100675 AES_VALIDATE_RET(ctx != NULL);
676 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000677
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100678 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
Gilles Peskineb71d4022023-03-16 17:14:59 +0100680 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200682 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100683 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200684 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100685 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000686
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200687 ctx->nr = cty.nr;
688
Gilles Peskine5511a342023-03-10 22:29:32 +0100689#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100690 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
691 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
692 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200693 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100694 }
695#endif
Gilles Peskinee7dc21f2023-03-10 22:37:11 +0100696#if defined(MBEDTLS_AESNI_HAVE_CODE)
697 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
698 /* The intrinsics-based implementation needs 16-byte alignment
699 * for the round key array. */
700 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
701 if (delta != 0) {
702 size_t rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
703 ctx->rk = RK = ctx->buf + rk_offset;
704 }
705 }
706#endif
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100707
Paul Bakker5121ce52009-01-03 21:22:43 +0000708 SK = cty.rk + cty.nr * 4;
709
710 *RK++ = *SK++;
711 *RK++ = *SK++;
712 *RK++ = *SK++;
713 *RK++ = *SK++;
714
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100715 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
716 for (j = 0; j < 4; j++, SK++) {
717 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
718 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
719 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
720 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000721 }
722 }
723
724 *RK++ = *SK++;
725 *RK++ = *SK++;
726 *RK++ = *SK++;
727 *RK++ = *SK++;
728
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200729exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100730 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000731
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100732 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000733}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100734#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100735
736#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100737static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
738 unsigned int keybits,
739 const unsigned char **key1,
740 unsigned int *key1bits,
741 const unsigned char **key2,
742 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100743{
744 const unsigned int half_keybits = keybits / 2;
745 const unsigned int half_keybytes = half_keybits / 8;
746
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100747 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100748 case 256: break;
749 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100750 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100751 }
752
753 *key1bits = half_keybits;
754 *key2bits = half_keybits;
755 *key1 = &key[0];
756 *key2 = &key[half_keybytes];
757
758 return 0;
759}
760
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100761int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
762 const unsigned char *key,
763 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100764{
Janos Follath24eed8d2019-11-22 13:21:35 +0000765 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100766 const unsigned char *key1, *key2;
767 unsigned int key1bits, key2bits;
768
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100769 AES_VALIDATE_RET(ctx != NULL);
770 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100771
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100772 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
773 &key2, &key2bits);
774 if (ret != 0) {
775 return ret;
776 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100777
778 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100779 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
780 if (ret != 0) {
781 return ret;
782 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100783
784 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100785 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100786}
787
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100788int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
789 const unsigned char *key,
790 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100791{
Janos Follath24eed8d2019-11-22 13:21:35 +0000792 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100793 const unsigned char *key1, *key2;
794 unsigned int key1bits, key2bits;
795
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100796 AES_VALIDATE_RET(ctx != NULL);
797 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100798
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100799 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
800 &key2, &key2bits);
801 if (ret != 0) {
802 return ret;
803 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100804
805 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100806 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
807 if (ret != 0) {
808 return ret;
809 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100810
811 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100812 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100813}
814#endif /* MBEDTLS_CIPHER_MODE_XTS */
815
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100816#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100817 do \
818 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100819 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
820 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
821 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
822 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100823 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100824 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
825 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
826 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
827 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100828 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100829 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
830 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
831 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
832 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100833 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100834 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
835 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
836 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
837 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
838 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100840#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100841 do \
842 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100843 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
844 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
845 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
846 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100847 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100848 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
849 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
850 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
851 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100852 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100853 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
854 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
855 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
856 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100857 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100858 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
859 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
860 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
861 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
862 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
864/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200865 * AES-ECB block encryption
866 */
867#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100868int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
869 const unsigned char input[16],
870 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200871{
872 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200873 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100874 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200875 uint32_t X[4];
876 uint32_t Y[4];
877 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200878
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100879 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
880 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
881 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
882 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200883
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
885 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]);
886 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 +0200887 }
888
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100889 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 +0200890
Gilles Peskine5197c662020-08-26 17:03:24 +0200891 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
893 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
894 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
895 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200896
Gilles Peskine5197c662020-08-26 17:03:24 +0200897 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100898 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
899 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
900 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
901 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200902
Gilles Peskine5197c662020-08-26 17:03:24 +0200903 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
905 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
906 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
907 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200908
Gilles Peskine5197c662020-08-26 17:03:24 +0200909 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100910 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
911 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
912 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
913 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200914
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100915 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
916 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
917 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
918 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000919
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100920 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500921
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100922 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200923}
924#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
925
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100926#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100927void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
928 const unsigned char input[16],
929 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100930{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100931 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100932}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100933#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100934
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200935/*
936 * AES-ECB block decryption
937 */
938#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100939int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
940 const unsigned char input[16],
941 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200942{
943 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200944 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100945 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200946 uint32_t X[4];
947 uint32_t Y[4];
948 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200949
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100950 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
951 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
952 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
953 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200954
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100955 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
956 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]);
957 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 +0200958 }
959
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100960 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 +0200961
Gilles Peskine5197c662020-08-26 17:03:24 +0200962 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100963 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
964 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
965 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
966 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Gilles Peskine5197c662020-08-26 17:03:24 +0200968 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100969 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
970 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
971 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
972 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Gilles Peskine5197c662020-08-26 17:03:24 +0200974 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100975 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
976 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
978 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200979
Gilles Peskine5197c662020-08-26 17:03:24 +0200980 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100981 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
982 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200985
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100986 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
987 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
988 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
989 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000990
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100991 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500992
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100993 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200994}
995#endif /* !MBEDTLS_AES_DECRYPT_ALT */
996
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100997#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100998void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
999 const unsigned char input[16],
1000 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +01001001{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001002 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +01001003}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001004#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001005
Gilles Peskineb71d4022023-03-16 17:14:59 +01001006#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine6978e732023-03-16 13:08:42 +01001007/* VIA Padlock and our intrinsics-based implementation of AESNI require
1008 * the round keys to be aligned on a 16-byte boundary. We take care of this
1009 * before creating them, but the AES context may have moved (this can happen
1010 * if the library is called from a language with managed memory), and in later
1011 * calls it might have a different alignment with respect to 16-byte memory.
1012 * So we may need to realign.
1013 * NOTE: In the LTS branch, the context contains a pointer to within itself,
1014 * so if it has been moved, things will probably go pear-shaped. We keep this
1015 * code for compatibility with the development branch, in case of future changes.
1016 */
1017static void aes_maybe_realign(mbedtls_aes_context *ctx)
1018{
1019 /* We want a 16-byte alignment. Note that rk and buf are pointers to uint32_t
1020 * and offset is in units of uint32_t words = 4 bytes. We want a
1021 * 4-word alignment. */
1022 unsigned current_offset = (unsigned)(ctx->rk - ctx->buf);
Gilles Peskineb71d4022023-03-16 17:14:59 +01001023 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1024 if (new_offset != current_offset) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001025 memmove(ctx->buf + new_offset, // new address
1026 ctx->buf + current_offset, // current address
1027 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1028 ctx->rk = ctx->buf + new_offset;
1029 }
1030}
1031#endif
1032
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001033/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001034 * AES-ECB block encryption/decryption
1035 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001036int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1037 int mode,
1038 const unsigned char input[16],
1039 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001040{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001041 AES_VALIDATE_RET(ctx != NULL);
1042 AES_VALIDATE_RET(input != NULL);
1043 AES_VALIDATE_RET(output != NULL);
1044 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1045 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001046
Gilles Peskineb71d4022023-03-16 17:14:59 +01001047#if defined(MAY_NEED_TO_ALIGN)
1048 aes_maybe_realign(ctx);
1049#endif
1050
Gilles Peskine5511a342023-03-10 22:29:32 +01001051#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001052 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1053 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1054 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001055#endif
1056
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001058 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001059 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 }
1061#endif
1062
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001063 if (mode == MBEDTLS_AES_ENCRYPT) {
1064 return mbedtls_internal_aes_encrypt(ctx, input, output);
1065 } else {
1066 return mbedtls_internal_aes_decrypt(ctx, input, output);
1067 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001068}
1069
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001070#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001071/*
1072 * AES-CBC buffer encryption/decryption
1073 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001074int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1075 int mode,
1076 size_t length,
1077 unsigned char iv[16],
1078 const unsigned char *input,
1079 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001080{
1081 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001082 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001083 unsigned char temp[16];
1084
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001085 AES_VALIDATE_RET(ctx != NULL);
1086 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1087 mode == MBEDTLS_AES_DECRYPT);
1088 AES_VALIDATE_RET(iv != NULL);
1089 AES_VALIDATE_RET(input != NULL);
1090 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001091
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001092 if (length % 16) {
1093 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1094 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001095
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001096#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001097 if (aes_padlock_ace) {
1098 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1099 return 0;
1100 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001101
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001102 // If padlock data misaligned, we just fall back to
1103 // unaccelerated mode
1104 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001105 }
1106#endif
1107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001108 if (mode == MBEDTLS_AES_DECRYPT) {
1109 while (length > 0) {
1110 memcpy(temp, input, 16);
1111 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1112 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001113 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001114 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001115
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001116 for (i = 0; i < 16; i++) {
1117 output[i] = (unsigned char) (output[i] ^ iv[i]);
1118 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001119
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001120 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001121
1122 input += 16;
1123 output += 16;
1124 length -= 16;
1125 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001126 } else {
1127 while (length > 0) {
1128 for (i = 0; i < 16; i++) {
1129 output[i] = (unsigned char) (input[i] ^ iv[i]);
1130 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001131
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001132 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1133 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001134 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001135 }
1136 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001137
1138 input += 16;
1139 output += 16;
1140 length -= 16;
1141 }
1142 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001143 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001144
Gilles Peskine377a3102021-07-07 21:08:28 +02001145exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001146 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001147}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001148#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001149
Aorimn5f778012016-06-09 23:22:58 +02001150#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001151
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001152typedef unsigned char mbedtls_be128[16];
1153
1154/*
1155 * GF(2^128) multiplication function
1156 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001157 * This function multiplies a field element by x in the polynomial field
1158 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001159 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001160 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001161 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001162static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1163 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001164{
1165 uint64_t a, b, ra, rb;
1166
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001167 a = MBEDTLS_GET_UINT64_LE(x, 0);
1168 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001169
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001170 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1171 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001172
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001173 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1174 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001175}
1176
Aorimn5f778012016-06-09 23:22:58 +02001177/*
1178 * AES-XTS buffer encryption/decryption
1179 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001180int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1181 int mode,
1182 size_t length,
1183 const unsigned char data_unit[16],
1184 const unsigned char *input,
1185 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001186{
Janos Follath24eed8d2019-11-22 13:21:35 +00001187 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001188 size_t blocks = length / 16;
1189 size_t leftover = length % 16;
1190 unsigned char tweak[16];
1191 unsigned char prev_tweak[16];
1192 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001193
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001194 AES_VALIDATE_RET(ctx != NULL);
1195 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1196 mode == MBEDTLS_AES_DECRYPT);
1197 AES_VALIDATE_RET(data_unit != NULL);
1198 AES_VALIDATE_RET(input != NULL);
1199 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001200
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001201 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001202 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001203 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001204 }
Aorimn5f778012016-06-09 23:22:58 +02001205
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001206 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001207 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001208 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001209 }
Aorimn5f778012016-06-09 23:22:58 +02001210
Jaeden Amerod82cd862018-04-28 15:02:45 +01001211 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001212 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1213 data_unit, tweak);
1214 if (ret != 0) {
1215 return ret;
1216 }
Aorimn5f778012016-06-09 23:22:58 +02001217
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001218 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001219 size_t i;
1220
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001221 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001222 /* We are on the last block in a decrypt operation that has
1223 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001224 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001225 * the leftovers and then update the current tweak for use on this,
1226 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001227 memcpy(prev_tweak, tweak, sizeof(tweak));
1228 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001229 }
1230
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001231 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001232 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001233 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001234
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001235 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1236 if (ret != 0) {
1237 return ret;
1238 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001240 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001242 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001243
1244 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001245 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001246
1247 output += 16;
1248 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001249 }
1250
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001251 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252 /* If we are on the leftover bytes in a decrypt operation, we need to
1253 * use the previous tweak for these bytes (as saved in prev_tweak). */
1254 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001255
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256 /* We are now on the final part of the data unit, which doesn't divide
1257 * evenly by 16. It's time for ciphertext stealing. */
1258 size_t i;
1259 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001260
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001262 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001263 * remainder of the input for this final round (since the loop bounds
1264 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001265 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 output[i] = prev_output[i];
1267 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001268 }
Aorimn5f778012016-06-09 23:22:58 +02001269
Jaeden Amerod82cd862018-04-28 15:02:45 +01001270 /* Copy ciphertext bytes from the previous block for input in this
1271 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001272 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001274 }
Aorimn5f778012016-06-09 23:22:58 +02001275
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001276 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1277 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001278 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001279 }
Aorimn5f778012016-06-09 23:22:58 +02001280
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281 /* Write the result back to the previous block, overriding the previous
1282 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001283 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001284 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001285 }
Aorimn5f778012016-06-09 23:22:58 +02001286 }
1287
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001288 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001289}
1290#endif /* MBEDTLS_CIPHER_MODE_XTS */
1291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001293/*
1294 * AES-CFB128 buffer encryption/decryption
1295 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001296int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1297 int mode,
1298 size_t length,
1299 size_t *iv_off,
1300 unsigned char iv[16],
1301 const unsigned char *input,
1302 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001303{
Paul Bakker27fdf462011-06-09 13:55:13 +00001304 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001305 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001306 size_t n;
1307
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001308 AES_VALIDATE_RET(ctx != NULL);
1309 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1310 mode == MBEDTLS_AES_DECRYPT);
1311 AES_VALIDATE_RET(iv_off != NULL);
1312 AES_VALIDATE_RET(iv != NULL);
1313 AES_VALIDATE_RET(input != NULL);
1314 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001315
1316 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001317
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001318 if (n > 15) {
1319 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1320 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001321
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001322 if (mode == MBEDTLS_AES_DECRYPT) {
1323 while (length--) {
1324 if (n == 0) {
1325 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1326 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001327 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001328 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001329 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001330
1331 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001332 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001333 iv[n] = (unsigned char) c;
1334
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001335 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001337 } else {
1338 while (length--) {
1339 if (n == 0) {
1340 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1341 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001342 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001343 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001344 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001345
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001346 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001347
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001348 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001349 }
1350 }
1351
1352 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001353 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001354
Gilles Peskine377a3102021-07-07 21:08:28 +02001355exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001356 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001357}
Paul Bakker556efba2014-01-24 15:38:12 +01001358
1359/*
1360 * AES-CFB8 buffer encryption/decryption
1361 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001362int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1363 int mode,
1364 size_t length,
1365 unsigned char iv[16],
1366 const unsigned char *input,
1367 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001368{
Gilles Peskine377a3102021-07-07 21:08:28 +02001369 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001370 unsigned char c;
1371 unsigned char ov[17];
1372
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001373 AES_VALIDATE_RET(ctx != NULL);
1374 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1375 mode == MBEDTLS_AES_DECRYPT);
1376 AES_VALIDATE_RET(iv != NULL);
1377 AES_VALIDATE_RET(input != NULL);
1378 AES_VALIDATE_RET(output != NULL);
1379 while (length--) {
1380 memcpy(ov, iv, 16);
1381 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1382 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001383 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001384 }
Paul Bakker556efba2014-01-24 15:38:12 +01001385
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001386 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001387 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001388 }
Paul Bakker556efba2014-01-24 15:38:12 +01001389
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001390 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001391
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001392 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001393 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001394 }
Paul Bakker556efba2014-01-24 15:38:12 +01001395
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001396 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001397 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001398 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001399
Gilles Peskine377a3102021-07-07 21:08:28 +02001400exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001401 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001402}
Simon Butcher76a5b222018-04-22 22:57:27 +01001403#endif /* MBEDTLS_CIPHER_MODE_CFB */
1404
1405#if defined(MBEDTLS_CIPHER_MODE_OFB)
1406/*
1407 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1408 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001409int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1410 size_t length,
1411 size_t *iv_off,
1412 unsigned char iv[16],
1413 const unsigned char *input,
1414 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001415{
Simon Butcherad4e4932018-04-29 00:43:47 +01001416 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001417 size_t n;
1418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001419 AES_VALIDATE_RET(ctx != NULL);
1420 AES_VALIDATE_RET(iv_off != NULL);
1421 AES_VALIDATE_RET(iv != NULL);
1422 AES_VALIDATE_RET(input != NULL);
1423 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001424
1425 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001426
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001427 if (n > 15) {
1428 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1429 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001430
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001431 while (length--) {
1432 if (n == 0) {
1433 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1434 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001435 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001436 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001437 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001438 *output++ = *input++ ^ iv[n];
1439
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001440 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001441 }
1442
1443 *iv_off = n;
1444
Simon Butcherad4e4932018-04-29 00:43:47 +01001445exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001446 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001447}
1448#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001449
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001450#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001451/*
1452 * AES-CTR buffer encryption/decryption
1453 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001454int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1455 size_t length,
1456 size_t *nc_off,
1457 unsigned char nonce_counter[16],
1458 unsigned char stream_block[16],
1459 const unsigned char *input,
1460 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001461{
Paul Bakker369e14b2012-04-18 14:16:09 +00001462 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001463 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001464 size_t n;
1465
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001466 AES_VALIDATE_RET(ctx != NULL);
1467 AES_VALIDATE_RET(nc_off != NULL);
1468 AES_VALIDATE_RET(nonce_counter != NULL);
1469 AES_VALIDATE_RET(stream_block != NULL);
1470 AES_VALIDATE_RET(input != NULL);
1471 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001472
1473 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001474
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001475 if (n > 0x0F) {
1476 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1477 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001478
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001479 while (length--) {
1480 if (n == 0) {
1481 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1482 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001483 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001484 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001485
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001486 for (i = 16; i > 0; i--) {
1487 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001488 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001489 }
1490 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001491 }
1492 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001493 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001494
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001495 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001496 }
1497
1498 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001499 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001500
Gilles Peskine377a3102021-07-07 21:08:28 +02001501exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001502 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001503}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001504#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001505
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001507
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001509/*
1510 * AES test vectors from:
1511 *
1512 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1513 */
1514static const unsigned char aes_test_ecb_dec[3][16] =
1515{
1516 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1517 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1518 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1519 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1520 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1521 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1522};
1523
1524static const unsigned char aes_test_ecb_enc[3][16] =
1525{
1526 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1527 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1528 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1529 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1530 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1531 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1532};
1533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001535static const unsigned char aes_test_cbc_dec[3][16] =
1536{
1537 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1538 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1539 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1540 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1541 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1542 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1543};
1544
1545static const unsigned char aes_test_cbc_enc[3][16] =
1546{
1547 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1548 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1549 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1550 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1551 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1552 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1553};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001554#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001555
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001556#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001557/*
1558 * AES-CFB128 test vectors from:
1559 *
1560 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1561 */
1562static const unsigned char aes_test_cfb128_key[3][32] =
1563{
1564 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1565 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1566 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1567 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1568 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1569 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1570 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1571 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1572 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1573};
1574
1575static const unsigned char aes_test_cfb128_iv[16] =
1576{
1577 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1578 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1579};
1580
1581static const unsigned char aes_test_cfb128_pt[64] =
1582{
1583 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1584 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1585 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1586 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1587 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1588 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1589 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1590 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1591};
1592
1593static const unsigned char aes_test_cfb128_ct[3][64] =
1594{
1595 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1596 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1597 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1598 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1599 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1600 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1601 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1602 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1603 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1604 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1605 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1606 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1607 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1608 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1609 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1610 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1611 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1612 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1613 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1614 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1615 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1616 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1617 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1618 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1619};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001620#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001621
Simon Butcherad4e4932018-04-29 00:43:47 +01001622#if defined(MBEDTLS_CIPHER_MODE_OFB)
1623/*
1624 * AES-OFB test vectors from:
1625 *
Simon Butcher5db13622018-06-04 22:11:25 +01001626 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001627 */
1628static const unsigned char aes_test_ofb_key[3][32] =
1629{
1630 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1631 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1632 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1633 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1634 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1635 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1636 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1637 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1638 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1639};
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
1659static const unsigned char aes_test_ofb_ct[3][64] =
1660{
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 },
1669 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1670 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1671 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1672 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1673 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1674 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1675 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1676 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1677 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1678 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1679 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1680 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1681 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1682 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1683 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1684 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1685};
1686#endif /* MBEDTLS_CIPHER_MODE_OFB */
1687
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001688#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001689/*
1690 * AES-CTR test vectors from:
1691 *
1692 * http://www.faqs.org/rfcs/rfc3686.html
1693 */
1694
1695static const unsigned char aes_test_ctr_key[3][16] =
1696{
1697 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1698 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1699 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1700 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1701 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1702 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1703};
1704
1705static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1706{
1707 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1708 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1709 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1710 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1711 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1712 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1713};
1714
1715static const unsigned char aes_test_ctr_pt[3][48] =
1716{
1717 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1718 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1719
1720 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1721 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1722 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1723 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1724
1725 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1726 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1727 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1728 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1729 0x20, 0x21, 0x22, 0x23 }
1730};
1731
1732static const unsigned char aes_test_ctr_ct[3][48] =
1733{
1734 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1735 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1736 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1737 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1738 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1739 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1740 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1741 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1742 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1743 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1744 0x25, 0xB2, 0x07, 0x2F }
1745};
1746
1747static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001748{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001749#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001750
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001751#if defined(MBEDTLS_CIPHER_MODE_XTS)
1752/*
1753 * AES-XTS test vectors from:
1754 *
1755 * IEEE P1619/D16 Annex B
1756 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1757 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1758 */
1759static const unsigned char aes_test_xts_key[][32] =
1760{
1761 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1766 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1767 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1768 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1769 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1770 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1771 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1772 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1773};
1774
1775static const unsigned char aes_test_xts_pt32[][32] =
1776{
1777 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1782 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1783 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1784 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1785 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1786 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};
1790
1791static const unsigned char aes_test_xts_ct32[][32] =
1792{
1793 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1794 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1795 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1796 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1797 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1798 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1799 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1800 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1801 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1802 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1803 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1804 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1805};
1806
1807static const unsigned char aes_test_xts_data_unit[][16] =
1808{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001809 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1811 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1813 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001815};
1816
1817#endif /* MBEDTLS_CIPHER_MODE_XTS */
1818
Paul Bakker5121ce52009-01-03 21:22:43 +00001819/*
1820 * Checkup routine
1821 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001822int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001823{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001824 int ret = 0, i, j, u, mode;
1825 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001826 unsigned char key[32];
1827 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001828 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001829#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1830 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001831 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001832#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001833#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001834 unsigned char prv[16];
1835#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001836#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1837 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001838 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001839#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001840#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001841 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001842#endif
1843#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001844 unsigned char nonce_counter[16];
1845 unsigned char stream_block[16];
1846#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001847 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001848
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001849 memset(key, 0, 32);
1850 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001851
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001852 if (verbose != 0) {
1853#if defined(MBEDTLS_AES_ALT)
1854 mbedtls_printf(" AES note: alternative implementation.\n");
1855#else /* MBEDTLS_AES_ALT */
1856#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1857 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1858 mbedtls_printf(" AES note: using VIA Padlock.\n");
1859 } else
1860#endif
1861#if defined(MBEDTLS_AESNI_HAVE_CODE)
1862 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1863 mbedtls_printf(" AES note: using AESNI.\n");
1864 } else
1865#endif
1866#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1867 if (mbedtls_aesce_has_support()) {
1868 mbedtls_printf(" AES note: using AESCE.\n");
1869 } else
1870#endif
1871 mbedtls_printf(" AES note: built-in implementation.\n");
1872#endif /* MBEDTLS_AES_ALT */
1873 }
1874
Paul Bakker5121ce52009-01-03 21:22:43 +00001875 /*
1876 * ECB mode
1877 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001878 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001879 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001880 keybits = 128 + u * 64;
1881 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001882
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001883 if (verbose != 0) {
1884 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1885 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001886 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001887
1888 memset(buf, 0, 16);
1889
1890 if (mode == MBEDTLS_AES_DECRYPT) {
1891 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1892 aes_tests = aes_test_ecb_dec[u];
1893 } else {
1894 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001895 aes_tests = aes_test_ecb_enc[u];
1896 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001897
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001898 /*
1899 * AES-192 is an optional feature that may be unavailable when
1900 * there is an alternative underlying implementation i.e. when
1901 * MBEDTLS_AES_ALT is defined.
1902 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001903 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1904 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001905 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001906 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001907 goto exit;
1908 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001909
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001910 for (j = 0; j < 10000; j++) {
1911 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1912 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001913 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001914 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001915 }
1916
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001917 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001918 ret = 1;
1919 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001920 }
1921
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001922 if (verbose != 0) {
1923 mbedtls_printf("passed\n");
1924 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001925 }
1926
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001927 if (verbose != 0) {
1928 mbedtls_printf("\n");
1929 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001930
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001931#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001932 /*
1933 * CBC mode
1934 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001935 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001936 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001937 keybits = 128 + u * 64;
1938 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001939
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001940 if (verbose != 0) {
1941 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1942 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001943 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001944
1945 memset(iv, 0, 16);
1946 memset(prv, 0, 16);
1947 memset(buf, 0, 16);
1948
1949 if (mode == MBEDTLS_AES_DECRYPT) {
1950 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1951 aes_tests = aes_test_cbc_dec[u];
1952 } else {
1953 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001954 aes_tests = aes_test_cbc_enc[u];
1955 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001956
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001957 /*
1958 * AES-192 is an optional feature that may be unavailable when
1959 * there is an alternative underlying implementation i.e. when
1960 * MBEDTLS_AES_ALT is defined.
1961 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001962 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1963 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001964 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001965 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001966 goto exit;
1967 }
1968
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001969 for (j = 0; j < 10000; j++) {
1970 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001971 unsigned char tmp[16];
1972
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001973 memcpy(tmp, prv, 16);
1974 memcpy(prv, buf, 16);
1975 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001976 }
1977
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001978 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1979 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001980 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001981 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001982
1983 }
1984
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001985 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001986 ret = 1;
1987 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001988 }
1989
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001990 if (verbose != 0) {
1991 mbedtls_printf("passed\n");
1992 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 }
1994
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001995 if (verbose != 0) {
1996 mbedtls_printf("\n");
1997 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001998#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001999
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002000#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002001 /*
2002 * CFB128 mode
2003 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002004 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002005 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002006 keybits = 128 + u * 64;
2007 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002008
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002009 if (verbose != 0) {
2010 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2011 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002013
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002014 memcpy(iv, aes_test_cfb128_iv, 16);
2015 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002016
2017 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002018 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002019 /*
2020 * AES-192 is an optional feature that may be unavailable when
2021 * there is an alternative underlying implementation i.e. when
2022 * MBEDTLS_AES_ALT is defined.
2023 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002024 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2025 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002026 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002027 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002028 goto exit;
2029 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002030
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002031 if (mode == MBEDTLS_AES_DECRYPT) {
2032 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002033 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002034 } else {
2035 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002036 aes_tests = aes_test_cfb128_ct[u];
2037 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002038
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002039 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2040 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002041 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002042 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002043
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002044 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002045 ret = 1;
2046 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002047 }
2048
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002049 if (verbose != 0) {
2050 mbedtls_printf("passed\n");
2051 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 }
2053
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002054 if (verbose != 0) {
2055 mbedtls_printf("\n");
2056 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002057#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002058
Simon Butcherad4e4932018-04-29 00:43:47 +01002059#if defined(MBEDTLS_CIPHER_MODE_OFB)
2060 /*
2061 * OFB mode
2062 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002063 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002064 u = i >> 1;
2065 keybits = 128 + u * 64;
2066 mode = i & 1;
2067
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002068 if (verbose != 0) {
2069 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2070 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2071 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002072
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002073 memcpy(iv, aes_test_ofb_iv, 16);
2074 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002075
2076 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002077 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002078 /*
2079 * AES-192 is an optional feature that may be unavailable when
2080 * there is an alternative underlying implementation i.e. when
2081 * MBEDTLS_AES_ALT is defined.
2082 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002083 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2084 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002085 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002086 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002087 goto exit;
2088 }
2089
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002090 if (mode == MBEDTLS_AES_DECRYPT) {
2091 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002092 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002093 } else {
2094 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002095 aes_tests = aes_test_ofb_ct[u];
2096 }
2097
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002098 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2099 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002100 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002101 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002103 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002104 ret = 1;
2105 goto exit;
2106 }
2107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002108 if (verbose != 0) {
2109 mbedtls_printf("passed\n");
2110 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002111 }
2112
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002113 if (verbose != 0) {
2114 mbedtls_printf("\n");
2115 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002116#endif /* MBEDTLS_CIPHER_MODE_OFB */
2117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002118#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002119 /*
2120 * CTR mode
2121 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002122 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002123 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002124 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002126 if (verbose != 0) {
2127 mbedtls_printf(" AES-CTR-128 (%s): ",
2128 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2129 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002130
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002131 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2132 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002133
2134 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002135 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002136 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002137 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002138
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002139 len = aes_test_ctr_len[u];
2140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002141 if (mode == MBEDTLS_AES_DECRYPT) {
2142 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002143 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002144 } else {
2145 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002146 aes_tests = aes_test_ctr_ct[u];
2147 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002148
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002149 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2150 stream_block, buf, buf);
2151 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002152 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002153 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002154
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002155 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002156 ret = 1;
2157 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002158 }
2159
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002160 if (verbose != 0) {
2161 mbedtls_printf("passed\n");
2162 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002163 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002164
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002165 if (verbose != 0) {
2166 mbedtls_printf("\n");
2167 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002168#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002169
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002170#if defined(MBEDTLS_CIPHER_MODE_XTS)
2171 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002172 static const int num_tests =
2173 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2174 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002175
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002176 /*
2177 * XTS mode
2178 */
2179 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002180
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002181 for (i = 0; i < num_tests << 1; i++) {
2182 const unsigned char *data_unit;
2183 u = i >> 1;
2184 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002185
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002186 if (verbose != 0) {
2187 mbedtls_printf(" AES-XTS-128 (%s): ",
2188 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2189 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002190
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002191 memset(key, 0, sizeof(key));
2192 memcpy(key, aes_test_xts_key[u], 32);
2193 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002194
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002195 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002196
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002197 if (mode == MBEDTLS_AES_DECRYPT) {
2198 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2199 if (ret != 0) {
2200 goto exit;
2201 }
2202 memcpy(buf, aes_test_xts_ct32[u], len);
2203 aes_tests = aes_test_xts_pt32[u];
2204 } else {
2205 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2206 if (ret != 0) {
2207 goto exit;
2208 }
2209 memcpy(buf, aes_test_xts_pt32[u], len);
2210 aes_tests = aes_test_xts_ct32[u];
2211 }
2212
2213
2214 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2215 buf, buf);
2216 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002217 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002218 }
2219
2220 if (memcmp(buf, aes_tests, len) != 0) {
2221 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002222 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002223 }
2224
2225 if (verbose != 0) {
2226 mbedtls_printf("passed\n");
2227 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002228 }
2229
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002230 if (verbose != 0) {
2231 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002232 }
2233
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002234 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002235 }
2236#endif /* MBEDTLS_CIPHER_MODE_XTS */
2237
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002238 ret = 0;
2239
2240exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002241 if (ret != 0 && verbose != 0) {
2242 mbedtls_printf("failed\n");
2243 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002244
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002245 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002247 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002248}
2249
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002250#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002251
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002252#endif /* MBEDTLS_AES_C */