blob: d02319e35e328a6db1bb06a9d6a0d556e3eac164 [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
Paul Bakker5121ce52009-01-03 21:22:43 +0000514/*
515 * AES key schedule (encryption)
516 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200517#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100518int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
519 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000520{
Paul Bakker23986e52011-04-24 08:57:21 +0000521 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000522 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100524 AES_VALIDATE_RET(ctx != NULL);
525 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100527 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 case 128: ctx->nr = 10; break;
529 case 192: ctx->nr = 12; break;
530 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100531 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000532 }
533
Simon Butcher5201e412018-12-06 17:40:14 +0000534#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100535 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000536 aes_gen_tables();
537 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000538 }
539#endif
540
Gilles Peskine30c356c2023-03-16 14:58:46 +0100541#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100542 if (aes_padlock_ace == -1) {
543 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
544 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000545
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100546 if (aes_padlock_ace) {
547 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16(ctx->buf);
548 } else
Paul Bakker5121ce52009-01-03 21:22:43 +0000549#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000550 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
Gilles Peskine5511a342023-03-10 22:29:32 +0100552#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100553 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Gilles Peskinee7dc21f2023-03-10 22:37:11 +0100554 /* The intrinsics-based implementation needs 16-byte alignment
555 * for the round key array. */
556 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
557 size_t rk_offset = 0;
558 if (delta != 0) {
559 rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
560 }
561 ctx->rk = RK = ctx->buf + rk_offset;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100562 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
563 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100564#endif
565
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100566 for (i = 0; i < (keybits >> 5); i++) {
567 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 }
569
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100570 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 case 10:
572
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100573 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000574 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100575 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
576 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
577 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
578 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
580 RK[5] = RK[1] ^ RK[4];
581 RK[6] = RK[2] ^ RK[5];
582 RK[7] = RK[3] ^ RK[6];
583 }
584 break;
585
586 case 12:
587
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100588 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100590 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
591 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
592 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
593 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000594
595 RK[7] = RK[1] ^ RK[6];
596 RK[8] = RK[2] ^ RK[7];
597 RK[9] = RK[3] ^ RK[8];
598 RK[10] = RK[4] ^ RK[9];
599 RK[11] = RK[5] ^ RK[10];
600 }
601 break;
602
603 case 14:
604
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100605 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000606 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100607 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
608 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
609 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
610 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 RK[9] = RK[1] ^ RK[8];
613 RK[10] = RK[2] ^ RK[9];
614 RK[11] = RK[3] ^ RK[10];
615
616 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100617 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
618 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
619 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
620 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622 RK[13] = RK[5] ^ RK[12];
623 RK[14] = RK[6] ^ RK[13];
624 RK[15] = RK[7] ^ RK[14];
625 }
626 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000628
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100629 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000630}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200631#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
633/*
634 * AES key schedule (decryption)
635 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200636#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100637int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
638 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000639{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200640 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000642 uint32_t *RK;
643 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200644
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100645 AES_VALIDATE_RET(ctx != NULL);
646 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000647
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100648 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
Gilles Peskine30c356c2023-03-16 14:58:46 +0100650#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100651 if (aes_padlock_ace == -1) {
652 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
653 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000654
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100655 if (aes_padlock_ace) {
656 ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16(ctx->buf);
657 } else
Paul Bakker5121ce52009-01-03 21:22:43 +0000658#endif
Paul Bakker048d04e2012-02-12 17:31:04 +0000659 ctx->rk = RK = ctx->buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000660
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200661 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100662 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200663 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100664 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000665
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200666 ctx->nr = cty.nr;
667
Gilles Peskine5511a342023-03-10 22:29:32 +0100668#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100669 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
670 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
671 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200672 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100673 }
674#endif
Gilles Peskinee7dc21f2023-03-10 22:37:11 +0100675#if defined(MBEDTLS_AESNI_HAVE_CODE)
676 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
677 /* The intrinsics-based implementation needs 16-byte alignment
678 * for the round key array. */
679 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
680 if (delta != 0) {
681 size_t rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
682 ctx->rk = RK = ctx->buf + rk_offset;
683 }
684 }
685#endif
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100686
Paul Bakker5121ce52009-01-03 21:22:43 +0000687 SK = cty.rk + cty.nr * 4;
688
689 *RK++ = *SK++;
690 *RK++ = *SK++;
691 *RK++ = *SK++;
692 *RK++ = *SK++;
693
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100694 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
695 for (j = 0; j < 4; j++, SK++) {
696 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
697 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
698 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
699 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000700 }
701 }
702
703 *RK++ = *SK++;
704 *RK++ = *SK++;
705 *RK++ = *SK++;
706 *RK++ = *SK++;
707
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200708exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100709 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000710
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100711 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000712}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100713#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100714
715#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100716static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
717 unsigned int keybits,
718 const unsigned char **key1,
719 unsigned int *key1bits,
720 const unsigned char **key2,
721 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100722{
723 const unsigned int half_keybits = keybits / 2;
724 const unsigned int half_keybytes = half_keybits / 8;
725
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100726 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100727 case 256: break;
728 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100729 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100730 }
731
732 *key1bits = half_keybits;
733 *key2bits = half_keybits;
734 *key1 = &key[0];
735 *key2 = &key[half_keybytes];
736
737 return 0;
738}
739
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100740int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
741 const unsigned char *key,
742 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100743{
Janos Follath24eed8d2019-11-22 13:21:35 +0000744 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100745 const unsigned char *key1, *key2;
746 unsigned int key1bits, key2bits;
747
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100748 AES_VALIDATE_RET(ctx != NULL);
749 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100750
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100751 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
752 &key2, &key2bits);
753 if (ret != 0) {
754 return ret;
755 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100756
757 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100758 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
759 if (ret != 0) {
760 return ret;
761 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100762
763 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100764 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100765}
766
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100767int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
768 const unsigned char *key,
769 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100770{
Janos Follath24eed8d2019-11-22 13:21:35 +0000771 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100772 const unsigned char *key1, *key2;
773 unsigned int key1bits, key2bits;
774
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100775 AES_VALIDATE_RET(ctx != NULL);
776 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100777
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100778 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
779 &key2, &key2bits);
780 if (ret != 0) {
781 return ret;
782 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100783
784 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100785 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
786 if (ret != 0) {
787 return ret;
788 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100789
790 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100791 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100792}
793#endif /* MBEDTLS_CIPHER_MODE_XTS */
794
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100795#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100796 do \
797 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100798 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
799 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
800 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
801 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100802 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100803 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
804 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
805 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
806 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100807 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100808 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
809 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
810 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
811 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100812 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100813 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
814 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
815 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
816 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
817 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000818
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100819#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100820 do \
821 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100822 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
823 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
824 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
825 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100826 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100827 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
828 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
829 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
830 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100831 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100832 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
833 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
834 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
835 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100836 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100837 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
838 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
839 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
840 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
841 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000842
843/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200844 * AES-ECB block encryption
845 */
846#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100847int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
848 const unsigned char input[16],
849 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200850{
851 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200852 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100853 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200854 uint32_t X[4];
855 uint32_t Y[4];
856 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200857
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100858 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
859 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
860 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
861 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200862
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100863 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
864 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]);
865 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 +0200866 }
867
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100868 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 +0200869
Gilles Peskine5197c662020-08-26 17:03:24 +0200870 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100871 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
872 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
873 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
874 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200875
Gilles Peskine5197c662020-08-26 17:03:24 +0200876 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100877 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
878 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
879 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
880 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200881
Gilles Peskine5197c662020-08-26 17:03:24 +0200882 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100883 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
884 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
885 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
886 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200887
Gilles Peskine5197c662020-08-26 17:03:24 +0200888 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100889 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
890 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
891 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
892 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200893
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100894 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
895 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
896 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
897 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000898
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100899 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500900
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100901 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200902}
903#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
904
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100905#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100906void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
907 const unsigned char input[16],
908 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100909{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100910 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100911}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100912#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100913
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200914/*
915 * AES-ECB block decryption
916 */
917#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100918int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
919 const unsigned char input[16],
920 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200921{
922 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200923 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100924 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200925 uint32_t X[4];
926 uint32_t Y[4];
927 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200928
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100929 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
930 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
931 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
932 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200933
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100934 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
935 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]);
936 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 +0200937 }
938
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100939 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 +0200940
Gilles Peskine5197c662020-08-26 17:03:24 +0200941 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100942 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
943 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
944 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
945 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200946
Gilles Peskine5197c662020-08-26 17:03:24 +0200947 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100948 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
949 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
950 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
951 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200952
Gilles Peskine5197c662020-08-26 17:03:24 +0200953 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100954 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
955 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
956 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
957 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200958
Gilles Peskine5197c662020-08-26 17:03:24 +0200959 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100960 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
961 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
962 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
963 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200964
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100965 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
966 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
967 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
968 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000969
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100970 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500971
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100972 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973}
974#endif /* !MBEDTLS_AES_DECRYPT_ALT */
975
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100976#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100977void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
978 const unsigned char input[16],
979 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100980{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100981 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100982}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100983#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100984
Gilles Peskine6978e732023-03-16 13:08:42 +0100985#if defined(MBEDTLS_AESNI_HAVE_CODE) || \
986 (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86))
987/* VIA Padlock and our intrinsics-based implementation of AESNI require
988 * the round keys to be aligned on a 16-byte boundary. We take care of this
989 * before creating them, but the AES context may have moved (this can happen
990 * if the library is called from a language with managed memory), and in later
991 * calls it might have a different alignment with respect to 16-byte memory.
992 * So we may need to realign.
993 * NOTE: In the LTS branch, the context contains a pointer to within itself,
994 * so if it has been moved, things will probably go pear-shaped. We keep this
995 * code for compatibility with the development branch, in case of future changes.
996 */
997static void aes_maybe_realign(mbedtls_aes_context *ctx)
998{
999 /* We want a 16-byte alignment. Note that rk and buf are pointers to uint32_t
1000 * and offset is in units of uint32_t words = 4 bytes. We want a
1001 * 4-word alignment. */
1002 unsigned current_offset = (unsigned)(ctx->rk - ctx->buf);
1003 uintptr_t current_address = (uintptr_t)ctx->rk;
1004 unsigned current_alignment = (current_address & 0x0000000f) / 4;
1005 if (current_alignment != 0) {
1006 unsigned new_offset = current_offset + 4 - current_alignment;
1007 if (new_offset >= 4) {
1008 new_offset -= 4;
1009 }
1010 memmove(ctx->buf + new_offset, // new address
1011 ctx->buf + current_offset, // current address
1012 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1013 ctx->rk = ctx->buf + new_offset;
1014 }
1015}
1016#endif
1017
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001018/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001019 * AES-ECB block encryption/decryption
1020 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001021int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1022 int mode,
1023 const unsigned char input[16],
1024 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001025{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001026 AES_VALIDATE_RET(ctx != NULL);
1027 AES_VALIDATE_RET(input != NULL);
1028 AES_VALIDATE_RET(output != NULL);
1029 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1030 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001031
Gilles Peskine5511a342023-03-10 22:29:32 +01001032#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001033 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001034 aes_maybe_realign(ctx);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001035 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1036 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001037#endif
1038
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001040 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001041 aes_maybe_realign(ctx);
1042 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001043 }
1044#endif
1045
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001046 if (mode == MBEDTLS_AES_ENCRYPT) {
1047 return mbedtls_internal_aes_encrypt(ctx, input, output);
1048 } else {
1049 return mbedtls_internal_aes_decrypt(ctx, input, output);
1050 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001051}
1052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001054/*
1055 * AES-CBC buffer encryption/decryption
1056 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001057int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1058 int mode,
1059 size_t length,
1060 unsigned char iv[16],
1061 const unsigned char *input,
1062 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001063{
1064 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001065 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001066 unsigned char temp[16];
1067
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001068 AES_VALIDATE_RET(ctx != NULL);
1069 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1070 mode == MBEDTLS_AES_DECRYPT);
1071 AES_VALIDATE_RET(iv != NULL);
1072 AES_VALIDATE_RET(input != NULL);
1073 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001074
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001075 if (length % 16) {
1076 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1077 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001078
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001079#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001080 if (aes_padlock_ace) {
1081 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1082 return 0;
1083 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001084
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001085 // If padlock data misaligned, we just fall back to
1086 // unaccelerated mode
1087 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001088 }
1089#endif
1090
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001091 if (mode == MBEDTLS_AES_DECRYPT) {
1092 while (length > 0) {
1093 memcpy(temp, input, 16);
1094 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1095 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001096 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001097 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001098
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001099 for (i = 0; i < 16; i++) {
1100 output[i] = (unsigned char) (output[i] ^ iv[i]);
1101 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001103 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001104
1105 input += 16;
1106 output += 16;
1107 length -= 16;
1108 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001109 } else {
1110 while (length > 0) {
1111 for (i = 0; i < 16; i++) {
1112 output[i] = (unsigned char) (input[i] ^ iv[i]);
1113 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001114
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001115 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1116 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001117 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001118 }
1119 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001120
1121 input += 16;
1122 output += 16;
1123 length -= 16;
1124 }
1125 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001126 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001127
Gilles Peskine377a3102021-07-07 21:08:28 +02001128exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001129 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001130}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001131#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001132
Aorimn5f778012016-06-09 23:22:58 +02001133#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001134
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001135typedef unsigned char mbedtls_be128[16];
1136
1137/*
1138 * GF(2^128) multiplication function
1139 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001140 * This function multiplies a field element by x in the polynomial field
1141 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001142 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001143 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001144 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001145static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1146 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001147{
1148 uint64_t a, b, ra, rb;
1149
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001150 a = MBEDTLS_GET_UINT64_LE(x, 0);
1151 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001152
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001153 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1154 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001155
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001156 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1157 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001158}
1159
Aorimn5f778012016-06-09 23:22:58 +02001160/*
1161 * AES-XTS buffer encryption/decryption
1162 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001163int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1164 int mode,
1165 size_t length,
1166 const unsigned char data_unit[16],
1167 const unsigned char *input,
1168 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001169{
Janos Follath24eed8d2019-11-22 13:21:35 +00001170 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001171 size_t blocks = length / 16;
1172 size_t leftover = length % 16;
1173 unsigned char tweak[16];
1174 unsigned char prev_tweak[16];
1175 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001177 AES_VALIDATE_RET(ctx != NULL);
1178 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1179 mode == MBEDTLS_AES_DECRYPT);
1180 AES_VALIDATE_RET(data_unit != NULL);
1181 AES_VALIDATE_RET(input != NULL);
1182 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001183
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001184 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001185 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001186 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001187 }
Aorimn5f778012016-06-09 23:22:58 +02001188
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001189 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001190 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001191 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001192 }
Aorimn5f778012016-06-09 23:22:58 +02001193
Jaeden Amerod82cd862018-04-28 15:02:45 +01001194 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001195 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1196 data_unit, tweak);
1197 if (ret != 0) {
1198 return ret;
1199 }
Aorimn5f778012016-06-09 23:22:58 +02001200
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001201 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001202 size_t i;
1203
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001204 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001205 /* We are on the last block in a decrypt operation that has
1206 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001207 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001208 * the leftovers and then update the current tweak for use on this,
1209 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001210 memcpy(prev_tweak, tweak, sizeof(tweak));
1211 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001212 }
1213
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001214 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001215 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001216 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001217
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001218 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1219 if (ret != 0) {
1220 return ret;
1221 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001222
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001223 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001224 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001225 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001226
1227 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001228 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001229
1230 output += 16;
1231 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001232 }
1233
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001234 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235 /* If we are on the leftover bytes in a decrypt operation, we need to
1236 * use the previous tweak for these bytes (as saved in prev_tweak). */
1237 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001238
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239 /* We are now on the final part of the data unit, which doesn't divide
1240 * evenly by 16. It's time for ciphertext stealing. */
1241 size_t i;
1242 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001243
Jaeden Amerod82cd862018-04-28 15:02:45 +01001244 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001245 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001246 * remainder of the input for this final round (since the loop bounds
1247 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001248 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001249 output[i] = prev_output[i];
1250 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001251 }
Aorimn5f778012016-06-09 23:22:58 +02001252
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253 /* Copy ciphertext bytes from the previous block for input in this
1254 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001255 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001257 }
Aorimn5f778012016-06-09 23:22:58 +02001258
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001259 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1260 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001262 }
Aorimn5f778012016-06-09 23:22:58 +02001263
Jaeden Amerod82cd862018-04-28 15:02:45 +01001264 /* Write the result back to the previous block, overriding the previous
1265 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001266 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001267 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001268 }
Aorimn5f778012016-06-09 23:22:58 +02001269 }
1270
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001271 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001272}
1273#endif /* MBEDTLS_CIPHER_MODE_XTS */
1274
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001275#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001276/*
1277 * AES-CFB128 buffer encryption/decryption
1278 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001279int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1280 int mode,
1281 size_t length,
1282 size_t *iv_off,
1283 unsigned char iv[16],
1284 const unsigned char *input,
1285 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001286{
Paul Bakker27fdf462011-06-09 13:55:13 +00001287 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001288 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001289 size_t n;
1290
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001291 AES_VALIDATE_RET(ctx != NULL);
1292 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1293 mode == MBEDTLS_AES_DECRYPT);
1294 AES_VALIDATE_RET(iv_off != NULL);
1295 AES_VALIDATE_RET(iv != NULL);
1296 AES_VALIDATE_RET(input != NULL);
1297 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001298
1299 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001300
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001301 if (n > 15) {
1302 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1303 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001305 if (mode == MBEDTLS_AES_DECRYPT) {
1306 while (length--) {
1307 if (n == 0) {
1308 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1309 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001310 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001311 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001312 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001313
1314 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001315 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001316 iv[n] = (unsigned char) c;
1317
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001318 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001319 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001320 } else {
1321 while (length--) {
1322 if (n == 0) {
1323 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1324 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001325 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001326 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001327 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001328
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001329 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001330
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001331 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001332 }
1333 }
1334
1335 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001336 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001337
Gilles Peskine377a3102021-07-07 21:08:28 +02001338exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001339 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001340}
Paul Bakker556efba2014-01-24 15:38:12 +01001341
1342/*
1343 * AES-CFB8 buffer encryption/decryption
1344 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001345int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1346 int mode,
1347 size_t length,
1348 unsigned char iv[16],
1349 const unsigned char *input,
1350 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001351{
Gilles Peskine377a3102021-07-07 21:08:28 +02001352 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001353 unsigned char c;
1354 unsigned char ov[17];
1355
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001356 AES_VALIDATE_RET(ctx != NULL);
1357 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1358 mode == MBEDTLS_AES_DECRYPT);
1359 AES_VALIDATE_RET(iv != NULL);
1360 AES_VALIDATE_RET(input != NULL);
1361 AES_VALIDATE_RET(output != NULL);
1362 while (length--) {
1363 memcpy(ov, iv, 16);
1364 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1365 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001366 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001367 }
Paul Bakker556efba2014-01-24 15:38:12 +01001368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001369 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001370 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001371 }
Paul Bakker556efba2014-01-24 15:38:12 +01001372
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001373 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001374
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001375 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001376 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001377 }
Paul Bakker556efba2014-01-24 15:38:12 +01001378
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001379 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001380 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001381 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001382
Gilles Peskine377a3102021-07-07 21:08:28 +02001383exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001384 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001385}
Simon Butcher76a5b222018-04-22 22:57:27 +01001386#endif /* MBEDTLS_CIPHER_MODE_CFB */
1387
1388#if defined(MBEDTLS_CIPHER_MODE_OFB)
1389/*
1390 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1391 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001392int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1393 size_t length,
1394 size_t *iv_off,
1395 unsigned char iv[16],
1396 const unsigned char *input,
1397 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001398{
Simon Butcherad4e4932018-04-29 00:43:47 +01001399 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001400 size_t n;
1401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001402 AES_VALIDATE_RET(ctx != NULL);
1403 AES_VALIDATE_RET(iv_off != NULL);
1404 AES_VALIDATE_RET(iv != NULL);
1405 AES_VALIDATE_RET(input != NULL);
1406 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001407
1408 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001409
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001410 if (n > 15) {
1411 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1412 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001413
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001414 while (length--) {
1415 if (n == 0) {
1416 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1417 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001418 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001419 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001420 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001421 *output++ = *input++ ^ iv[n];
1422
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001423 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001424 }
1425
1426 *iv_off = n;
1427
Simon Butcherad4e4932018-04-29 00:43:47 +01001428exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001429 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001430}
1431#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001433#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001434/*
1435 * AES-CTR buffer encryption/decryption
1436 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001437int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1438 size_t length,
1439 size_t *nc_off,
1440 unsigned char nonce_counter[16],
1441 unsigned char stream_block[16],
1442 const unsigned char *input,
1443 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001444{
Paul Bakker369e14b2012-04-18 14:16:09 +00001445 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001446 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001447 size_t n;
1448
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001449 AES_VALIDATE_RET(ctx != NULL);
1450 AES_VALIDATE_RET(nc_off != NULL);
1451 AES_VALIDATE_RET(nonce_counter != NULL);
1452 AES_VALIDATE_RET(stream_block != NULL);
1453 AES_VALIDATE_RET(input != NULL);
1454 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001455
1456 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001457
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001458 if (n > 0x0F) {
1459 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1460 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001461
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001462 while (length--) {
1463 if (n == 0) {
1464 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1465 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001466 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001467 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001468
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001469 for (i = 16; i > 0; i--) {
1470 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001471 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001472 }
1473 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001474 }
1475 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001476 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001478 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001479 }
1480
1481 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001482 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483
Gilles Peskine377a3102021-07-07 21:08:28 +02001484exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001485 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001486}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001492/*
1493 * AES test vectors from:
1494 *
1495 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1496 */
1497static const unsigned char aes_test_ecb_dec[3][16] =
1498{
1499 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1500 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1501 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1502 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1503 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1504 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1505};
1506
1507static const unsigned char aes_test_ecb_enc[3][16] =
1508{
1509 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1510 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1511 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1512 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1513 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1514 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1515};
1516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001517#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001518static const unsigned char aes_test_cbc_dec[3][16] =
1519{
1520 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1521 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1522 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1523 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1524 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1525 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1526};
1527
1528static const unsigned char aes_test_cbc_enc[3][16] =
1529{
1530 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1531 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1532 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1533 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1534 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1535 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1536};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001537#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001538
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001539#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001540/*
1541 * AES-CFB128 test vectors from:
1542 *
1543 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1544 */
1545static const unsigned char aes_test_cfb128_key[3][32] =
1546{
1547 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1548 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1549 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1550 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1551 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1552 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1553 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1554 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1555 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1556};
1557
1558static const unsigned char aes_test_cfb128_iv[16] =
1559{
1560 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1561 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1562};
1563
1564static const unsigned char aes_test_cfb128_pt[64] =
1565{
1566 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1567 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1568 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1569 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1570 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1571 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1572 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1573 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1574};
1575
1576static const unsigned char aes_test_cfb128_ct[3][64] =
1577{
1578 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1579 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1580 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1581 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1582 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1583 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1584 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1585 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1586 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1587 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1588 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1589 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1590 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1591 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1592 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1593 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1594 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1595 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1596 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1597 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1598 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1599 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1600 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1601 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1602};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001603#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001604
Simon Butcherad4e4932018-04-29 00:43:47 +01001605#if defined(MBEDTLS_CIPHER_MODE_OFB)
1606/*
1607 * AES-OFB test vectors from:
1608 *
Simon Butcher5db13622018-06-04 22:11:25 +01001609 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001610 */
1611static const unsigned char aes_test_ofb_key[3][32] =
1612{
1613 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1614 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1615 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1616 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1617 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1618 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1619 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1620 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1621 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1622};
1623
1624static const unsigned char aes_test_ofb_iv[16] =
1625{
1626 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1627 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1628};
1629
1630static const unsigned char aes_test_ofb_pt[64] =
1631{
1632 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1633 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1634 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1635 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1636 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1637 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1638 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1639 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1640};
1641
1642static const unsigned char aes_test_ofb_ct[3][64] =
1643{
1644 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1645 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1646 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1647 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1648 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1649 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1650 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1651 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1652 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1653 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1654 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1655 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1656 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1657 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1658 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1659 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1660 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1661 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1662 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1663 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1664 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1665 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1666 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1667 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1668};
1669#endif /* MBEDTLS_CIPHER_MODE_OFB */
1670
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001671#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001672/*
1673 * AES-CTR test vectors from:
1674 *
1675 * http://www.faqs.org/rfcs/rfc3686.html
1676 */
1677
1678static const unsigned char aes_test_ctr_key[3][16] =
1679{
1680 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1681 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1682 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1683 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1684 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1685 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1686};
1687
1688static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1689{
1690 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1692 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1693 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1694 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1695 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1696};
1697
1698static const unsigned char aes_test_ctr_pt[3][48] =
1699{
1700 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1701 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1702
1703 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1704 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1705 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1706 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1707
1708 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1709 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1710 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1711 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1712 0x20, 0x21, 0x22, 0x23 }
1713};
1714
1715static const unsigned char aes_test_ctr_ct[3][48] =
1716{
1717 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1718 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1719 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1720 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1721 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1722 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1723 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1724 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1725 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1726 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1727 0x25, 0xB2, 0x07, 0x2F }
1728};
1729
1730static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001731{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001732#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001733
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001734#if defined(MBEDTLS_CIPHER_MODE_XTS)
1735/*
1736 * AES-XTS test vectors from:
1737 *
1738 * IEEE P1619/D16 Annex B
1739 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1740 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1741 */
1742static const unsigned char aes_test_xts_key[][32] =
1743{
1744 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1745 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1746 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1747 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1748 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1749 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1750 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1751 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1752 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1753 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1754 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1755 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1756};
1757
1758static const unsigned char aes_test_xts_pt32[][32] =
1759{
1760 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1765 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1766 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1767 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1768 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1769 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1770 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1771 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1772};
1773
1774static const unsigned char aes_test_xts_ct32[][32] =
1775{
1776 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1777 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1778 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1779 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1780 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1781 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1782 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1783 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1784 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1785 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1786 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1787 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1788};
1789
1790static const unsigned char aes_test_xts_data_unit[][16] =
1791{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001792 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1794 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1796 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001798};
1799
1800#endif /* MBEDTLS_CIPHER_MODE_XTS */
1801
Paul Bakker5121ce52009-01-03 21:22:43 +00001802/*
1803 * Checkup routine
1804 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001805int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001806{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001807 int ret = 0, i, j, u, mode;
1808 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001809 unsigned char key[32];
1810 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001811 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001812#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1813 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001814 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001815#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001816#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001817 unsigned char prv[16];
1818#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001819#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1820 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001821 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001822#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001823#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001824 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001825#endif
1826#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001827 unsigned char nonce_counter[16];
1828 unsigned char stream_block[16];
1829#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001830 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001831
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001832 memset(key, 0, 32);
1833 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001834
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001835 if (verbose != 0) {
1836#if defined(MBEDTLS_AES_ALT)
1837 mbedtls_printf(" AES note: alternative implementation.\n");
1838#else /* MBEDTLS_AES_ALT */
1839#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1840 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1841 mbedtls_printf(" AES note: using VIA Padlock.\n");
1842 } else
1843#endif
1844#if defined(MBEDTLS_AESNI_HAVE_CODE)
1845 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1846 mbedtls_printf(" AES note: using AESNI.\n");
1847 } else
1848#endif
1849#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1850 if (mbedtls_aesce_has_support()) {
1851 mbedtls_printf(" AES note: using AESCE.\n");
1852 } else
1853#endif
1854 mbedtls_printf(" AES note: built-in implementation.\n");
1855#endif /* MBEDTLS_AES_ALT */
1856 }
1857
Paul Bakker5121ce52009-01-03 21:22:43 +00001858 /*
1859 * ECB mode
1860 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001861 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001862 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001863 keybits = 128 + u * 64;
1864 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001865
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001866 if (verbose != 0) {
1867 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1868 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001869 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001870
1871 memset(buf, 0, 16);
1872
1873 if (mode == MBEDTLS_AES_DECRYPT) {
1874 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1875 aes_tests = aes_test_ecb_dec[u];
1876 } else {
1877 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001878 aes_tests = aes_test_ecb_enc[u];
1879 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001880
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001881 /*
1882 * AES-192 is an optional feature that may be unavailable when
1883 * there is an alternative underlying implementation i.e. when
1884 * MBEDTLS_AES_ALT is defined.
1885 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001886 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1887 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001888 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001889 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001890 goto exit;
1891 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001892
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001893 for (j = 0; j < 10000; j++) {
1894 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1895 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001896 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001897 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001898 }
1899
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001900 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001901 ret = 1;
1902 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 }
1904
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001905 if (verbose != 0) {
1906 mbedtls_printf("passed\n");
1907 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001908 }
1909
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001910 if (verbose != 0) {
1911 mbedtls_printf("\n");
1912 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001913
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001914#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001915 /*
1916 * CBC mode
1917 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001918 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001919 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001920 keybits = 128 + u * 64;
1921 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001923 if (verbose != 0) {
1924 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1925 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001926 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001927
1928 memset(iv, 0, 16);
1929 memset(prv, 0, 16);
1930 memset(buf, 0, 16);
1931
1932 if (mode == MBEDTLS_AES_DECRYPT) {
1933 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1934 aes_tests = aes_test_cbc_dec[u];
1935 } else {
1936 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001937 aes_tests = aes_test_cbc_enc[u];
1938 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001939
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001940 /*
1941 * AES-192 is an optional feature that may be unavailable when
1942 * there is an alternative underlying implementation i.e. when
1943 * MBEDTLS_AES_ALT is defined.
1944 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001945 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1946 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001947 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001948 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001949 goto exit;
1950 }
1951
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001952 for (j = 0; j < 10000; j++) {
1953 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001954 unsigned char tmp[16];
1955
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001956 memcpy(tmp, prv, 16);
1957 memcpy(prv, buf, 16);
1958 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 }
1960
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001961 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1962 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001963 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001964 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001965
1966 }
1967
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001968 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001969 ret = 1;
1970 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001971 }
1972
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001973 if (verbose != 0) {
1974 mbedtls_printf("passed\n");
1975 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001976 }
1977
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001978 if (verbose != 0) {
1979 mbedtls_printf("\n");
1980 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001981#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001982
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001983#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001984 /*
1985 * CFB128 mode
1986 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001987 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001988 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001989 keybits = 128 + u * 64;
1990 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001991
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001992 if (verbose != 0) {
1993 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1994 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1995 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001996
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001997 memcpy(iv, aes_test_cfb128_iv, 16);
1998 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001999
2000 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002001 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002002 /*
2003 * AES-192 is an optional feature that may be unavailable when
2004 * there is an alternative underlying implementation i.e. when
2005 * MBEDTLS_AES_ALT is defined.
2006 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002007 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2008 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002009 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002010 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002011 goto exit;
2012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002013
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002014 if (mode == MBEDTLS_AES_DECRYPT) {
2015 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002016 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002017 } else {
2018 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002019 aes_tests = aes_test_cfb128_ct[u];
2020 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002021
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002022 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2023 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002024 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002025 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002026
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002027 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002028 ret = 1;
2029 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002030 }
2031
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002032 if (verbose != 0) {
2033 mbedtls_printf("passed\n");
2034 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002035 }
2036
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002037 if (verbose != 0) {
2038 mbedtls_printf("\n");
2039 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002040#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002041
Simon Butcherad4e4932018-04-29 00:43:47 +01002042#if defined(MBEDTLS_CIPHER_MODE_OFB)
2043 /*
2044 * OFB mode
2045 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002046 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002047 u = i >> 1;
2048 keybits = 128 + u * 64;
2049 mode = i & 1;
2050
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002051 if (verbose != 0) {
2052 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2053 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2054 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002055
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002056 memcpy(iv, aes_test_ofb_iv, 16);
2057 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002058
2059 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002060 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002061 /*
2062 * AES-192 is an optional feature that may be unavailable when
2063 * there is an alternative underlying implementation i.e. when
2064 * MBEDTLS_AES_ALT is defined.
2065 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002066 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2067 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002068 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002069 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002070 goto exit;
2071 }
2072
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002073 if (mode == MBEDTLS_AES_DECRYPT) {
2074 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002075 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002076 } else {
2077 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002078 aes_tests = aes_test_ofb_ct[u];
2079 }
2080
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002081 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2082 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002083 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002084 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002085
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002086 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002087 ret = 1;
2088 goto exit;
2089 }
2090
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002091 if (verbose != 0) {
2092 mbedtls_printf("passed\n");
2093 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002094 }
2095
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002096 if (verbose != 0) {
2097 mbedtls_printf("\n");
2098 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002099#endif /* MBEDTLS_CIPHER_MODE_OFB */
2100
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002101#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002102 /*
2103 * CTR mode
2104 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002105 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002106 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002107 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002108
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002109 if (verbose != 0) {
2110 mbedtls_printf(" AES-CTR-128 (%s): ",
2111 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2112 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002113
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002114 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2115 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002116
2117 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002118 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002119 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002120 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002121
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002122 len = aes_test_ctr_len[u];
2123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002124 if (mode == MBEDTLS_AES_DECRYPT) {
2125 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002126 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002127 } else {
2128 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002129 aes_tests = aes_test_ctr_ct[u];
2130 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002131
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002132 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2133 stream_block, buf, buf);
2134 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002135 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002136 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002137
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002138 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002139 ret = 1;
2140 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002141 }
2142
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002143 if (verbose != 0) {
2144 mbedtls_printf("passed\n");
2145 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002146 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002147
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002148 if (verbose != 0) {
2149 mbedtls_printf("\n");
2150 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002152
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002153#if defined(MBEDTLS_CIPHER_MODE_XTS)
2154 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002155 static const int num_tests =
2156 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2157 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002159 /*
2160 * XTS mode
2161 */
2162 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002163
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002164 for (i = 0; i < num_tests << 1; i++) {
2165 const unsigned char *data_unit;
2166 u = i >> 1;
2167 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002168
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002169 if (verbose != 0) {
2170 mbedtls_printf(" AES-XTS-128 (%s): ",
2171 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2172 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002173
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002174 memset(key, 0, sizeof(key));
2175 memcpy(key, aes_test_xts_key[u], 32);
2176 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002177
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002178 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002179
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002180 if (mode == MBEDTLS_AES_DECRYPT) {
2181 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2182 if (ret != 0) {
2183 goto exit;
2184 }
2185 memcpy(buf, aes_test_xts_ct32[u], len);
2186 aes_tests = aes_test_xts_pt32[u];
2187 } else {
2188 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2189 if (ret != 0) {
2190 goto exit;
2191 }
2192 memcpy(buf, aes_test_xts_pt32[u], len);
2193 aes_tests = aes_test_xts_ct32[u];
2194 }
2195
2196
2197 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2198 buf, buf);
2199 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002200 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002201 }
2202
2203 if (memcmp(buf, aes_tests, len) != 0) {
2204 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002205 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002206 }
2207
2208 if (verbose != 0) {
2209 mbedtls_printf("passed\n");
2210 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002211 }
2212
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002213 if (verbose != 0) {
2214 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002215 }
2216
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002217 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002218 }
2219#endif /* MBEDTLS_CIPHER_MODE_XTS */
2220
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002221 ret = 0;
2222
2223exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002224 if (ret != 0 && verbose != 0) {
2225 mbedtls_printf("failed\n");
2226 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002227
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002228 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002229
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002230 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002231}
2232
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002233#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002235#endif /* MBEDTLS_AES_C */