blob: 062ac8fa3d43ec9fee6ae6f9f03bba14f064784a [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
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100354#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000355/*
356 * Round constants
357 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000358static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360/*
361 * Tables generation code
362 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100363#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
364#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
365#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367static int aes_init_done = 0;
368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100369static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000370{
371 int i, x, y, z;
372 int pow[256];
373 int log[256];
374
375 /*
376 * compute pow and log tables over GF(2^8)
377 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100378 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000379 pow[i] = x;
380 log[x] = i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100381 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000382 }
383
384 /*
385 * calculate the round constants
386 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000388 RCON[i] = (uint32_t) x;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100389 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000390 }
391
392 /*
393 * generate the forward and reverse S-boxes
394 */
395 FSb[0x00] = 0x63;
396 RSb[0x63] = 0x00;
397
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100398 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 x = pow[255 - log[i]];
400
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100401 y = x; 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));
404 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 x ^= y ^ 0x63;
406
407 FSb[i] = (unsigned char) x;
408 RSb[x] = (unsigned char) i;
409 }
410
411 /*
412 * generate the forward and reverse tables
413 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100414 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 x = FSb[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100416 y = MBEDTLS_BYTE_0(XTIME(x));
417 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100419 FT0[i] = ((uint32_t) y) ^
420 ((uint32_t) x << 8) ^
421 ((uint32_t) x << 16) ^
422 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
Hanno Beckerad049a92017-06-19 16:31:54 +0100424#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100425 FT1[i] = ROTL8(FT0[i]);
426 FT2[i] = ROTL8(FT1[i]);
427 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100428#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430 x = RSb[i];
431
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100432 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
433 ((uint32_t) MUL(0x09, x) << 8) ^
434 ((uint32_t) MUL(0x0D, x) << 16) ^
435 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
Hanno Beckerad049a92017-06-19 16:31:54 +0100437#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100438 RT1[i] = ROTL8(RT0[i]);
439 RT2[i] = ROTL8(RT1[i]);
440 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100441#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 }
443}
444
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100445#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
446
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200447#undef ROTL8
448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
Hanno Beckerad049a92017-06-19 16:31:54 +0100451#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200452
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100453#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
454#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
455#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456
457#define AES_RT0(idx) RT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100458#define AES_RT1(idx) ROTL8(RT0[idx])
459#define AES_RT2(idx) ROTL16(RT0[idx])
460#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200461
462#define AES_FT0(idx) FT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100463#define AES_FT1(idx) ROTL8(FT0[idx])
464#define AES_FT2(idx) ROTL16(FT0[idx])
465#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200466
Hanno Becker177d3cf2017-06-07 15:52:48 +0100467#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200468
469#define AES_RT0(idx) RT0[idx]
470#define AES_RT1(idx) RT1[idx]
471#define AES_RT2(idx) RT2[idx]
472#define AES_RT3(idx) RT3[idx]
473
474#define AES_FT0(idx) FT0[idx]
475#define AES_FT1(idx) FT1[idx]
476#define AES_FT2(idx) FT2[idx]
477#define AES_FT3(idx) FT3[idx]
478
Hanno Becker177d3cf2017-06-07 15:52:48 +0100479#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200480
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100481void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200482{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100483 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000484
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100485 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200486}
487
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100488void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200489{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100490 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200491 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100492 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200493
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100494 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200495}
496
Jaeden Amero9366feb2018-05-29 18:55:17 +0100497#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100498void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100499{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100500 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000501
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502 mbedtls_aes_init(&ctx->crypt);
503 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100504}
505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100507{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100508 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100509 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100510 }
Simon Butcher5201e412018-12-06 17:40:14 +0000511
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100512 mbedtls_aes_free(&ctx->crypt);
513 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100514}
515#endif /* MBEDTLS_CIPHER_MODE_XTS */
516
Gilles Peskineb71d4022023-03-16 17:14:59 +0100517/* Some implementations need the round keys to be aligned.
518 * Return an offset to be added to buf, such that (buf + offset) is
519 * correctly aligned.
520 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
521 * i.e. an offset of 1 means 4 bytes and so on.
522 */
523#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine6dec5412023-03-16 17:21:33 +0100524 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100525#define MAY_NEED_TO_ALIGN
526#endif
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100527
528#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100529static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
530{
531#if defined(MAY_NEED_TO_ALIGN)
532 int align_16_bytes = 0;
533
534#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
535 if (aes_padlock_ace == -1) {
536 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
537 }
538 if (aes_padlock_ace) {
539 align_16_bytes = 1;
540 }
541#endif
542
Gilles Peskine6dec5412023-03-16 17:21:33 +0100543#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskineb71d4022023-03-16 17:14:59 +0100544 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
545 align_16_bytes = 1;
546 }
547#endif
548
549 if (align_16_bytes) {
550 /* These implementations needs 16-byte alignment
551 * for the round key array. */
552 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
553 if (delta == 0) {
554 return 0;
555 } else {
556 return 4 - delta; // 16 bytes = 4 uint32_t
557 }
558 }
559#else /* MAY_NEED_TO_ALIGN */
560 (void) buf;
561#endif /* MAY_NEED_TO_ALIGN */
562
563 return 0;
564}
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100565#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskineb71d4022023-03-16 17:14:59 +0100566
Paul Bakker5121ce52009-01-03 21:22:43 +0000567/*
568 * AES key schedule (encryption)
569 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200570#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100571int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
572 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000573{
Paul Bakker23986e52011-04-24 08:57:21 +0000574 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000575 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100577 AES_VALIDATE_RET(ctx != NULL);
578 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100580 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000581 case 128: ctx->nr = 10; break;
582 case 192: ctx->nr = 12; break;
583 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100584 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000585 }
586
Simon Butcher5201e412018-12-06 17:40:14 +0000587#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100588 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000589 aes_gen_tables();
590 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000591 }
592#endif
593
Gilles Peskineb71d4022023-03-16 17:14:59 +0100594 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000595
Gilles Peskine5511a342023-03-10 22:29:32 +0100596#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100597 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
598 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
599 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100600#endif
601
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100602 for (i = 0; i < (keybits >> 5); i++) {
603 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000604 }
605
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100606 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000607 case 10:
608
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100609 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000610 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100611 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
612 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
613 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
614 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
616 RK[5] = RK[1] ^ RK[4];
617 RK[6] = RK[2] ^ RK[5];
618 RK[7] = RK[3] ^ RK[6];
619 }
620 break;
621
622 case 12:
623
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000625 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100626 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
627 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
628 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
629 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
631 RK[7] = RK[1] ^ RK[6];
632 RK[8] = RK[2] ^ RK[7];
633 RK[9] = RK[3] ^ RK[8];
634 RK[10] = RK[4] ^ RK[9];
635 RK[11] = RK[5] ^ RK[10];
636 }
637 break;
638
639 case 14:
640
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100641 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000642 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100643 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
644 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
645 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
646 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000647
648 RK[9] = RK[1] ^ RK[8];
649 RK[10] = RK[2] ^ RK[9];
650 RK[11] = RK[3] ^ RK[10];
651
652 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100653 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
654 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
655 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
656 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000657
658 RK[13] = RK[5] ^ RK[12];
659 RK[14] = RK[6] ^ RK[13];
660 RK[15] = RK[7] ^ RK[14];
661 }
662 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000664
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100665 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000666}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200667#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
669/*
670 * AES key schedule (decryption)
671 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200672#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100673int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
674 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000675{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200676 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000678 uint32_t *RK;
679 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200680
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100681 AES_VALIDATE_RET(ctx != NULL);
682 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000683
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100684 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000685
Gilles Peskineb71d4022023-03-16 17:14:59 +0100686 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200688 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100689 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200690 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100691 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000692
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200693 ctx->nr = cty.nr;
694
Gilles Peskine5511a342023-03-10 22:29:32 +0100695#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100696 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
697 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
698 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200699 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100700 }
701#endif
702
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 SK = cty.rk + cty.nr * 4;
704
705 *RK++ = *SK++;
706 *RK++ = *SK++;
707 *RK++ = *SK++;
708 *RK++ = *SK++;
709
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100710 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
711 for (j = 0; j < 4; j++, SK++) {
712 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
713 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
714 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
715 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 }
717 }
718
719 *RK++ = *SK++;
720 *RK++ = *SK++;
721 *RK++ = *SK++;
722 *RK++ = *SK++;
723
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200724exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100725 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000726
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100727 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000728}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100729#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100730
731#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100732static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
733 unsigned int keybits,
734 const unsigned char **key1,
735 unsigned int *key1bits,
736 const unsigned char **key2,
737 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100738{
739 const unsigned int half_keybits = keybits / 2;
740 const unsigned int half_keybytes = half_keybits / 8;
741
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100742 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100743 case 256: break;
744 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100745 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100746 }
747
748 *key1bits = half_keybits;
749 *key2bits = half_keybits;
750 *key1 = &key[0];
751 *key2 = &key[half_keybytes];
752
753 return 0;
754}
755
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100756int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
757 const unsigned char *key,
758 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100759{
Janos Follath24eed8d2019-11-22 13:21:35 +0000760 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100761 const unsigned char *key1, *key2;
762 unsigned int key1bits, key2bits;
763
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100764 AES_VALIDATE_RET(ctx != NULL);
765 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100766
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100767 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
768 &key2, &key2bits);
769 if (ret != 0) {
770 return ret;
771 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100772
773 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100774 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
775 if (ret != 0) {
776 return ret;
777 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100778
779 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100780 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100781}
782
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100783int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
784 const unsigned char *key,
785 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100786{
Janos Follath24eed8d2019-11-22 13:21:35 +0000787 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100788 const unsigned char *key1, *key2;
789 unsigned int key1bits, key2bits;
790
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100791 AES_VALIDATE_RET(ctx != NULL);
792 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100793
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100794 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
795 &key2, &key2bits);
796 if (ret != 0) {
797 return ret;
798 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100799
800 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100801 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
802 if (ret != 0) {
803 return ret;
804 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100805
806 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100807 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808}
809#endif /* MBEDTLS_CIPHER_MODE_XTS */
810
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100811#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100812 do \
813 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100814 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
815 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
816 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
817 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100818 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100819 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
820 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
821 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
822 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100823 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100824 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
825 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
826 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
827 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100828 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100829 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
830 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
831 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
832 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
833 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000834
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100835#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100836 do \
837 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100838 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
839 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
840 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
841 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100842 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100843 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
844 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
845 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
846 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100847 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100848 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
849 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
850 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
851 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100852 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100853 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
854 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
855 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
856 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
857 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000858
859/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200860 * AES-ECB block encryption
861 */
862#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100863int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
864 const unsigned char input[16],
865 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200866{
867 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200868 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100869 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200870 uint32_t X[4];
871 uint32_t Y[4];
872 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200873
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100874 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
875 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
876 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
877 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200878
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100879 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
880 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]);
881 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 +0200882 }
883
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884 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 +0200885
Gilles Peskine5197c662020-08-26 17:03:24 +0200886 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100887 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
888 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
889 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
890 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200891
Gilles Peskine5197c662020-08-26 17:03:24 +0200892 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100893 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
894 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
895 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
896 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200897
Gilles Peskine5197c662020-08-26 17:03:24 +0200898 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100899 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
900 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
901 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
902 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200903
Gilles Peskine5197c662020-08-26 17:03:24 +0200904 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100905 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
906 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
907 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
908 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200909
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100910 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
911 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
912 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
913 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000914
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100915 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500916
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100917 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200918}
919#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
920
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100921#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100922void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
923 const unsigned char input[16],
924 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100925{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100926 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100927}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100928#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100929
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200930/*
931 * AES-ECB block decryption
932 */
933#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100934int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
935 const unsigned char input[16],
936 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200937{
938 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200939 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100940 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200941 uint32_t X[4];
942 uint32_t Y[4];
943 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200944
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100945 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
946 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
947 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
948 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200949
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100950 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
951 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]);
952 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 +0200953 }
954
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100955 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 +0200956
Gilles Peskine5197c662020-08-26 17:03:24 +0200957 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100958 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
959 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
960 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
961 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Gilles Peskine5197c662020-08-26 17:03:24 +0200963 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100964 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
965 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
966 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
967 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200968
Gilles Peskine5197c662020-08-26 17:03:24 +0200969 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100970 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
971 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
972 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
973 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200974
Gilles Peskine5197c662020-08-26 17:03:24 +0200975 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100976 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
978 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
979 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200980
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100981 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
982 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
983 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
984 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000985
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100986 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500987
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100988 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200989}
990#endif /* !MBEDTLS_AES_DECRYPT_ALT */
991
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100992#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100993void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
994 const unsigned char input[16],
995 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100996{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100997 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100998}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100999#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001000
Gilles Peskineb71d4022023-03-16 17:14:59 +01001001#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine6978e732023-03-16 13:08:42 +01001002/* VIA Padlock and our intrinsics-based implementation of AESNI require
1003 * the round keys to be aligned on a 16-byte boundary. We take care of this
1004 * before creating them, but the AES context may have moved (this can happen
1005 * if the library is called from a language with managed memory), and in later
1006 * calls it might have a different alignment with respect to 16-byte memory.
1007 * So we may need to realign.
1008 * NOTE: In the LTS branch, the context contains a pointer to within itself,
1009 * so if it has been moved, things will probably go pear-shaped. We keep this
1010 * code for compatibility with the development branch, in case of future changes.
1011 */
1012static void aes_maybe_realign(mbedtls_aes_context *ctx)
1013{
Tom Cosgrove2c942a32023-03-19 14:04:04 +00001014 unsigned current_offset = (unsigned) (ctx->rk - ctx->buf);
Gilles Peskineb71d4022023-03-16 17:14:59 +01001015 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1016 if (new_offset != current_offset) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001017 memmove(ctx->buf + new_offset, // new address
1018 ctx->buf + current_offset, // current address
1019 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1020 ctx->rk = ctx->buf + new_offset;
1021 }
1022}
1023#endif
1024
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001025/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001026 * AES-ECB block encryption/decryption
1027 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001028int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1029 int mode,
1030 const unsigned char input[16],
1031 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001032{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001033 AES_VALIDATE_RET(ctx != NULL);
1034 AES_VALIDATE_RET(input != NULL);
1035 AES_VALIDATE_RET(output != NULL);
1036 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1037 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001038
Gilles Peskineb71d4022023-03-16 17:14:59 +01001039#if defined(MAY_NEED_TO_ALIGN)
1040 aes_maybe_realign(ctx);
1041#endif
1042
Gilles Peskine5511a342023-03-10 22:29:32 +01001043#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001044 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1045 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1046 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001047#endif
1048
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001050 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001051 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001052 }
1053#endif
1054
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001055 if (mode == MBEDTLS_AES_ENCRYPT) {
1056 return mbedtls_internal_aes_encrypt(ctx, input, output);
1057 } else {
1058 return mbedtls_internal_aes_decrypt(ctx, input, output);
1059 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001060}
1061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001063/*
1064 * AES-CBC buffer encryption/decryption
1065 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001066int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1067 int mode,
1068 size_t length,
1069 unsigned char iv[16],
1070 const unsigned char *input,
1071 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001072{
1073 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001074 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001075 unsigned char temp[16];
1076
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001077 AES_VALIDATE_RET(ctx != NULL);
1078 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1079 mode == MBEDTLS_AES_DECRYPT);
1080 AES_VALIDATE_RET(iv != NULL);
1081 AES_VALIDATE_RET(input != NULL);
1082 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001083
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001084 if (length % 16) {
1085 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1086 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001087
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001089 if (aes_padlock_ace) {
1090 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1091 return 0;
1092 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001093
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001094 // If padlock data misaligned, we just fall back to
1095 // unaccelerated mode
1096 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001097 }
1098#endif
1099
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001100 if (mode == MBEDTLS_AES_DECRYPT) {
1101 while (length > 0) {
1102 memcpy(temp, input, 16);
1103 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1104 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001105 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001106 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001108 for (i = 0; i < 16; i++) {
1109 output[i] = (unsigned char) (output[i] ^ iv[i]);
1110 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001111
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001112 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001113
1114 input += 16;
1115 output += 16;
1116 length -= 16;
1117 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001118 } else {
1119 while (length > 0) {
1120 for (i = 0; i < 16; i++) {
1121 output[i] = (unsigned char) (input[i] ^ iv[i]);
1122 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001123
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001124 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1125 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001126 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001127 }
1128 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001129
1130 input += 16;
1131 output += 16;
1132 length -= 16;
1133 }
1134 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001135 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001136
Gilles Peskine377a3102021-07-07 21:08:28 +02001137exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001138 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001139}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
Aorimn5f778012016-06-09 23:22:58 +02001142#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001143
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001144typedef unsigned char mbedtls_be128[16];
1145
1146/*
1147 * GF(2^128) multiplication function
1148 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001149 * This function multiplies a field element by x in the polynomial field
1150 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001151 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001152 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001153 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001154static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1155 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001156{
1157 uint64_t a, b, ra, rb;
1158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001159 a = MBEDTLS_GET_UINT64_LE(x, 0);
1160 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001161
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001162 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1163 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001164
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001165 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1166 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001167}
1168
Aorimn5f778012016-06-09 23:22:58 +02001169/*
1170 * AES-XTS buffer encryption/decryption
1171 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001172int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1173 int mode,
1174 size_t length,
1175 const unsigned char data_unit[16],
1176 const unsigned char *input,
1177 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001178{
Janos Follath24eed8d2019-11-22 13:21:35 +00001179 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001180 size_t blocks = length / 16;
1181 size_t leftover = length % 16;
1182 unsigned char tweak[16];
1183 unsigned char prev_tweak[16];
1184 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001185
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001186 AES_VALIDATE_RET(ctx != NULL);
1187 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1188 mode == MBEDTLS_AES_DECRYPT);
1189 AES_VALIDATE_RET(data_unit != NULL);
1190 AES_VALIDATE_RET(input != NULL);
1191 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001192
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001193 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001194 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001195 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001196 }
Aorimn5f778012016-06-09 23:22:58 +02001197
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001198 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001199 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001200 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001201 }
Aorimn5f778012016-06-09 23:22:58 +02001202
Jaeden Amerod82cd862018-04-28 15:02:45 +01001203 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001204 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1205 data_unit, tweak);
1206 if (ret != 0) {
1207 return ret;
1208 }
Aorimn5f778012016-06-09 23:22:58 +02001209
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001210 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001211 size_t i;
1212
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001213 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001214 /* We are on the last block in a decrypt operation that has
1215 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001216 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001217 * the leftovers and then update the current tweak for use on this,
1218 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001219 memcpy(prev_tweak, tweak, sizeof(tweak));
1220 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 }
1222
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001223 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001224 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001225 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001226
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001227 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1228 if (ret != 0) {
1229 return ret;
1230 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001231
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001232 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001233 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001234 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235
1236 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001237 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001238
1239 output += 16;
1240 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001241 }
1242
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001243 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001244 /* If we are on the leftover bytes in a decrypt operation, we need to
1245 * use the previous tweak for these bytes (as saved in prev_tweak). */
1246 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001247
Jaeden Amerod82cd862018-04-28 15:02:45 +01001248 /* We are now on the final part of the data unit, which doesn't divide
1249 * evenly by 16. It's time for ciphertext stealing. */
1250 size_t i;
1251 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001252
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001254 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001255 * remainder of the input for this final round (since the loop bounds
1256 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001257 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001258 output[i] = prev_output[i];
1259 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001260 }
Aorimn5f778012016-06-09 23:22:58 +02001261
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 /* Copy ciphertext bytes from the previous block for input in this
1263 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001264 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001266 }
Aorimn5f778012016-06-09 23:22:58 +02001267
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001268 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1269 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001270 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001271 }
Aorimn5f778012016-06-09 23:22:58 +02001272
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 /* Write the result back to the previous block, overriding the previous
1274 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001275 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001277 }
Aorimn5f778012016-06-09 23:22:58 +02001278 }
1279
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001280 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001281}
1282#endif /* MBEDTLS_CIPHER_MODE_XTS */
1283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001284#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001285/*
1286 * AES-CFB128 buffer encryption/decryption
1287 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001288int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1289 int mode,
1290 size_t length,
1291 size_t *iv_off,
1292 unsigned char iv[16],
1293 const unsigned char *input,
1294 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001295{
Paul Bakker27fdf462011-06-09 13:55:13 +00001296 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001297 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001298 size_t n;
1299
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001300 AES_VALIDATE_RET(ctx != NULL);
1301 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1302 mode == MBEDTLS_AES_DECRYPT);
1303 AES_VALIDATE_RET(iv_off != NULL);
1304 AES_VALIDATE_RET(iv != NULL);
1305 AES_VALIDATE_RET(input != NULL);
1306 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001307
1308 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001310 if (n > 15) {
1311 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1312 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001314 if (mode == MBEDTLS_AES_DECRYPT) {
1315 while (length--) {
1316 if (n == 0) {
1317 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1318 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001319 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001320 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001321 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001322
1323 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001324 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001325 iv[n] = (unsigned char) c;
1326
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001327 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001328 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001329 } else {
1330 while (length--) {
1331 if (n == 0) {
1332 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1333 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001334 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001335 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001336 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001337
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001338 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001339
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001340 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001341 }
1342 }
1343
1344 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001345 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001346
Gilles Peskine377a3102021-07-07 21:08:28 +02001347exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001348 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001349}
Paul Bakker556efba2014-01-24 15:38:12 +01001350
1351/*
1352 * AES-CFB8 buffer encryption/decryption
1353 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001354int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1355 int mode,
1356 size_t length,
1357 unsigned char iv[16],
1358 const unsigned char *input,
1359 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001360{
Gilles Peskine377a3102021-07-07 21:08:28 +02001361 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001362 unsigned char c;
1363 unsigned char ov[17];
1364
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001365 AES_VALIDATE_RET(ctx != NULL);
1366 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1367 mode == MBEDTLS_AES_DECRYPT);
1368 AES_VALIDATE_RET(iv != NULL);
1369 AES_VALIDATE_RET(input != NULL);
1370 AES_VALIDATE_RET(output != NULL);
1371 while (length--) {
1372 memcpy(ov, iv, 16);
1373 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1374 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001375 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001376 }
Paul Bakker556efba2014-01-24 15:38:12 +01001377
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001378 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001379 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001380 }
Paul Bakker556efba2014-01-24 15:38:12 +01001381
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001382 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001383
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001384 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001385 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001386 }
Paul Bakker556efba2014-01-24 15:38:12 +01001387
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001388 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001389 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001390 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001391
Gilles Peskine377a3102021-07-07 21:08:28 +02001392exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001393 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001394}
Simon Butcher76a5b222018-04-22 22:57:27 +01001395#endif /* MBEDTLS_CIPHER_MODE_CFB */
1396
1397#if defined(MBEDTLS_CIPHER_MODE_OFB)
1398/*
1399 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1400 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001401int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1402 size_t length,
1403 size_t *iv_off,
1404 unsigned char iv[16],
1405 const unsigned char *input,
1406 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001407{
Simon Butcherad4e4932018-04-29 00:43:47 +01001408 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001409 size_t n;
1410
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001411 AES_VALIDATE_RET(ctx != NULL);
1412 AES_VALIDATE_RET(iv_off != NULL);
1413 AES_VALIDATE_RET(iv != NULL);
1414 AES_VALIDATE_RET(input != NULL);
1415 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001416
1417 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001418
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001419 if (n > 15) {
1420 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1421 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001422
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001423 while (length--) {
1424 if (n == 0) {
1425 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1426 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001427 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001428 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001429 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001430 *output++ = *input++ ^ iv[n];
1431
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001432 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001433 }
1434
1435 *iv_off = n;
1436
Simon Butcherad4e4932018-04-29 00:43:47 +01001437exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001438 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001439}
1440#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001442#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001443/*
1444 * AES-CTR buffer encryption/decryption
1445 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001446int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1447 size_t length,
1448 size_t *nc_off,
1449 unsigned char nonce_counter[16],
1450 unsigned char stream_block[16],
1451 const unsigned char *input,
1452 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001453{
Paul Bakker369e14b2012-04-18 14:16:09 +00001454 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001455 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001456 size_t n;
1457
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001458 AES_VALIDATE_RET(ctx != NULL);
1459 AES_VALIDATE_RET(nc_off != NULL);
1460 AES_VALIDATE_RET(nonce_counter != NULL);
1461 AES_VALIDATE_RET(stream_block != NULL);
1462 AES_VALIDATE_RET(input != NULL);
1463 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001464
1465 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001466
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001467 if (n > 0x0F) {
1468 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1469 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001470
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001471 while (length--) {
1472 if (n == 0) {
1473 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1474 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001475 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001476 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001477
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001478 for (i = 16; i > 0; i--) {
1479 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001480 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001481 }
1482 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483 }
1484 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001485 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001487 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001488 }
1489
1490 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001491 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001492
Gilles Peskine377a3102021-07-07 21:08:28 +02001493exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001494 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001495}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001496#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001498#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001499
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001500#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001501/*
1502 * AES test vectors from:
1503 *
1504 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1505 */
1506static const unsigned char aes_test_ecb_dec[3][16] =
1507{
1508 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1509 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1510 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1511 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1512 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1513 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1514};
1515
1516static const unsigned char aes_test_ecb_enc[3][16] =
1517{
1518 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1519 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1520 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1521 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1522 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1523 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1524};
1525
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001527static const unsigned char aes_test_cbc_dec[3][16] =
1528{
1529 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1530 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1531 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1532 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1533 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1534 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1535};
1536
1537static const unsigned char aes_test_cbc_enc[3][16] =
1538{
1539 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1540 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1541 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1542 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1543 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1544 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1545};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001546#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001547
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001548#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001549/*
1550 * AES-CFB128 test vectors from:
1551 *
1552 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1553 */
1554static const unsigned char aes_test_cfb128_key[3][32] =
1555{
1556 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1557 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1558 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1559 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1560 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1561 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1562 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1563 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1564 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1565};
1566
1567static const unsigned char aes_test_cfb128_iv[16] =
1568{
1569 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1570 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1571};
1572
1573static const unsigned char aes_test_cfb128_pt[64] =
1574{
1575 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1576 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1577 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1578 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1579 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1580 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1581 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1582 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1583};
1584
1585static const unsigned char aes_test_cfb128_ct[3][64] =
1586{
1587 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1588 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1589 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1590 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1591 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1592 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1593 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1594 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1595 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1596 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1597 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1598 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1599 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1600 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1601 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1602 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1603 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1604 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1605 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1606 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1607 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1608 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1609 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1610 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1611};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001613
Simon Butcherad4e4932018-04-29 00:43:47 +01001614#if defined(MBEDTLS_CIPHER_MODE_OFB)
1615/*
1616 * AES-OFB test vectors from:
1617 *
Simon Butcher5db13622018-06-04 22:11:25 +01001618 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001619 */
1620static const unsigned char aes_test_ofb_key[3][32] =
1621{
1622 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1623 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1624 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1625 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1626 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1627 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1628 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1629 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1630 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1631};
1632
1633static const unsigned char aes_test_ofb_iv[16] =
1634{
1635 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1636 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1637};
1638
1639static const unsigned char aes_test_ofb_pt[64] =
1640{
1641 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1642 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1643 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1644 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1645 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1646 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1647 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1648 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1649};
1650
1651static const unsigned char aes_test_ofb_ct[3][64] =
1652{
1653 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1654 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1655 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1656 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1657 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1658 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1659 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1660 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1661 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1662 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1663 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1664 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1665 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1666 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1667 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1668 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1669 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1670 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1671 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1672 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1673 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1674 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1675 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1676 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1677};
1678#endif /* MBEDTLS_CIPHER_MODE_OFB */
1679
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001680#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001681/*
1682 * AES-CTR test vectors from:
1683 *
1684 * http://www.faqs.org/rfcs/rfc3686.html
1685 */
1686
1687static const unsigned char aes_test_ctr_key[3][16] =
1688{
1689 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1690 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1691 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1692 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1693 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1694 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1695};
1696
1697static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1698{
1699 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1701 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1702 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1703 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1704 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1705};
1706
1707static const unsigned char aes_test_ctr_pt[3][48] =
1708{
1709 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1710 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1711
1712 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1713 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1714 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1715 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1716
1717 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1718 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1719 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1720 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1721 0x20, 0x21, 0x22, 0x23 }
1722};
1723
1724static const unsigned char aes_test_ctr_ct[3][48] =
1725{
1726 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1727 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1728 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1729 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1730 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1731 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1732 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1733 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1734 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1735 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1736 0x25, 0xB2, 0x07, 0x2F }
1737};
1738
1739static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001740{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001741#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001742
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001743#if defined(MBEDTLS_CIPHER_MODE_XTS)
1744/*
1745 * AES-XTS test vectors from:
1746 *
1747 * IEEE P1619/D16 Annex B
1748 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1749 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1750 */
1751static const unsigned char aes_test_xts_key[][32] =
1752{
1753 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1757 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1758 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1759 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1760 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1761 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1762 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1763 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1764 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1765};
1766
1767static const unsigned char aes_test_xts_pt32[][32] =
1768{
1769 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1773 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1774 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1775 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1776 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1777 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1778 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1779 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1780 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1781};
1782
1783static const unsigned char aes_test_xts_ct32[][32] =
1784{
1785 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1786 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1787 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1788 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1789 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1790 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1791 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1792 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1793 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1794 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1795 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1796 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1797};
1798
1799static const unsigned char aes_test_xts_data_unit[][16] =
1800{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001801 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1803 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1805 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001807};
1808
1809#endif /* MBEDTLS_CIPHER_MODE_XTS */
1810
Paul Bakker5121ce52009-01-03 21:22:43 +00001811/*
1812 * Checkup routine
1813 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001814int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001815{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001816 int ret = 0, i, j, u, mode;
1817 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001818 unsigned char key[32];
1819 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001820 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001821#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1822 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001824#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001826 unsigned char prv[16];
1827#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001828#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1829 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001830 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001831#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001832#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001833 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001834#endif
1835#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001836 unsigned char nonce_counter[16];
1837 unsigned char stream_block[16];
1838#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001839 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001841 memset(key, 0, 32);
1842 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001843
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001844 if (verbose != 0) {
1845#if defined(MBEDTLS_AES_ALT)
1846 mbedtls_printf(" AES note: alternative implementation.\n");
1847#else /* MBEDTLS_AES_ALT */
1848#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1849 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1850 mbedtls_printf(" AES note: using VIA Padlock.\n");
1851 } else
1852#endif
1853#if defined(MBEDTLS_AESNI_HAVE_CODE)
1854 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Tom Cosgrove20458c02023-03-18 14:48:49 +00001855 mbedtls_printf(" AES note: using AESNI via ");
1856#if MBEDTLS_AESNI_HAVE_CODE == 1
1857 mbedtls_printf("assembly");
1858#elif MBEDTLS_AESNI_HAVE_CODE == 2
1859 mbedtls_printf("intrinsics");
1860#else
1861 mbedtls_printf("(unknown)");
1862#endif
1863 mbedtls_printf(".\n");
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001864 } else
1865#endif
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001866 mbedtls_printf(" AES note: built-in implementation.\n");
1867#endif /* MBEDTLS_AES_ALT */
1868 }
1869
Paul Bakker5121ce52009-01-03 21:22:43 +00001870 /*
1871 * ECB mode
1872 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001873 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001874 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001875 keybits = 128 + u * 64;
1876 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001877
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001878 if (verbose != 0) {
1879 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1880 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001881 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001882
1883 memset(buf, 0, 16);
1884
1885 if (mode == MBEDTLS_AES_DECRYPT) {
1886 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1887 aes_tests = aes_test_ecb_dec[u];
1888 } else {
1889 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001890 aes_tests = aes_test_ecb_enc[u];
1891 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001892
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001893 /*
1894 * AES-192 is an optional feature that may be unavailable when
1895 * there is an alternative underlying implementation i.e. when
1896 * MBEDTLS_AES_ALT is defined.
1897 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001898 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1899 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001900 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001901 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001902 goto exit;
1903 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001904
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001905 for (j = 0; j < 10000; j++) {
1906 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1907 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001908 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001909 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001910 }
1911
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001912 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001913 ret = 1;
1914 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001915 }
1916
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001917 if (verbose != 0) {
1918 mbedtls_printf("passed\n");
1919 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001920 }
1921
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001922 if (verbose != 0) {
1923 mbedtls_printf("\n");
1924 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001925
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001926#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001927 /*
1928 * CBC mode
1929 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001930 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001931 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001932 keybits = 128 + u * 64;
1933 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001934
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001935 if (verbose != 0) {
1936 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1937 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001938 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001939
1940 memset(iv, 0, 16);
1941 memset(prv, 0, 16);
1942 memset(buf, 0, 16);
1943
1944 if (mode == MBEDTLS_AES_DECRYPT) {
1945 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1946 aes_tests = aes_test_cbc_dec[u];
1947 } else {
1948 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001949 aes_tests = aes_test_cbc_enc[u];
1950 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001951
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001952 /*
1953 * AES-192 is an optional feature that may be unavailable when
1954 * there is an alternative underlying implementation i.e. when
1955 * MBEDTLS_AES_ALT is defined.
1956 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001957 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1958 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001959 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001960 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001961 goto exit;
1962 }
1963
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001964 for (j = 0; j < 10000; j++) {
1965 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001966 unsigned char tmp[16];
1967
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001968 memcpy(tmp, prv, 16);
1969 memcpy(prv, buf, 16);
1970 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001971 }
1972
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001973 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1974 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001975 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001976 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001977
1978 }
1979
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001980 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001981 ret = 1;
1982 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001983 }
1984
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001985 if (verbose != 0) {
1986 mbedtls_printf("passed\n");
1987 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001988 }
1989
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001990 if (verbose != 0) {
1991 mbedtls_printf("\n");
1992 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001993#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001994
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001995#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001996 /*
1997 * CFB128 mode
1998 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001999 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002000 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002001 keybits = 128 + u * 64;
2002 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002003
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002004 if (verbose != 0) {
2005 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2006 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2007 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002008
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002009 memcpy(iv, aes_test_cfb128_iv, 16);
2010 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002011
2012 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002013 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002014 /*
2015 * AES-192 is an optional feature that may be unavailable when
2016 * there is an alternative underlying implementation i.e. when
2017 * MBEDTLS_AES_ALT is defined.
2018 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002019 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2020 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002021 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002022 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002023 goto exit;
2024 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002025
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002026 if (mode == MBEDTLS_AES_DECRYPT) {
2027 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002028 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002029 } else {
2030 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002031 aes_tests = aes_test_cfb128_ct[u];
2032 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002033
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002034 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2035 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002036 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002037 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002038
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002039 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002040 ret = 1;
2041 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002042 }
2043
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002044 if (verbose != 0) {
2045 mbedtls_printf("passed\n");
2046 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002047 }
2048
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002049 if (verbose != 0) {
2050 mbedtls_printf("\n");
2051 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002052#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002053
Simon Butcherad4e4932018-04-29 00:43:47 +01002054#if defined(MBEDTLS_CIPHER_MODE_OFB)
2055 /*
2056 * OFB mode
2057 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002058 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002059 u = i >> 1;
2060 keybits = 128 + u * 64;
2061 mode = i & 1;
2062
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002063 if (verbose != 0) {
2064 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2065 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2066 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002067
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002068 memcpy(iv, aes_test_ofb_iv, 16);
2069 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002070
2071 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002072 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002073 /*
2074 * AES-192 is an optional feature that may be unavailable when
2075 * there is an alternative underlying implementation i.e. when
2076 * MBEDTLS_AES_ALT is defined.
2077 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002078 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2079 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002080 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002081 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002082 goto exit;
2083 }
2084
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002085 if (mode == MBEDTLS_AES_DECRYPT) {
2086 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002087 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002088 } else {
2089 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002090 aes_tests = aes_test_ofb_ct[u];
2091 }
2092
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002093 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2094 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002095 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002096 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002097
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002098 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002099 ret = 1;
2100 goto exit;
2101 }
2102
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002103 if (verbose != 0) {
2104 mbedtls_printf("passed\n");
2105 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002106 }
2107
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002108 if (verbose != 0) {
2109 mbedtls_printf("\n");
2110 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002111#endif /* MBEDTLS_CIPHER_MODE_OFB */
2112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002113#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002114 /*
2115 * CTR mode
2116 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002117 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002118 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002119 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002120
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002121 if (verbose != 0) {
2122 mbedtls_printf(" AES-CTR-128 (%s): ",
2123 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2124 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002125
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002126 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2127 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002128
2129 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002130 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002131 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002132 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002133
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002134 len = aes_test_ctr_len[u];
2135
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002136 if (mode == MBEDTLS_AES_DECRYPT) {
2137 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002138 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002139 } else {
2140 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002141 aes_tests = aes_test_ctr_ct[u];
2142 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002143
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002144 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2145 stream_block, buf, buf);
2146 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002147 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002148 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002149
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002150 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002151 ret = 1;
2152 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002153 }
2154
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002155 if (verbose != 0) {
2156 mbedtls_printf("passed\n");
2157 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002158 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002159
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002160 if (verbose != 0) {
2161 mbedtls_printf("\n");
2162 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002163#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002164
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002165#if defined(MBEDTLS_CIPHER_MODE_XTS)
2166 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002167 static const int num_tests =
2168 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2169 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002170
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002171 /*
2172 * XTS mode
2173 */
2174 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002175
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002176 for (i = 0; i < num_tests << 1; i++) {
2177 const unsigned char *data_unit;
2178 u = i >> 1;
2179 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002180
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002181 if (verbose != 0) {
2182 mbedtls_printf(" AES-XTS-128 (%s): ",
2183 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2184 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002185
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002186 memset(key, 0, sizeof(key));
2187 memcpy(key, aes_test_xts_key[u], 32);
2188 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002189
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002190 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002191
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002192 if (mode == MBEDTLS_AES_DECRYPT) {
2193 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2194 if (ret != 0) {
2195 goto exit;
2196 }
2197 memcpy(buf, aes_test_xts_ct32[u], len);
2198 aes_tests = aes_test_xts_pt32[u];
2199 } else {
2200 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2201 if (ret != 0) {
2202 goto exit;
2203 }
2204 memcpy(buf, aes_test_xts_pt32[u], len);
2205 aes_tests = aes_test_xts_ct32[u];
2206 }
2207
2208
2209 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2210 buf, buf);
2211 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002212 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002213 }
2214
2215 if (memcmp(buf, aes_tests, len) != 0) {
2216 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002217 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002218 }
2219
2220 if (verbose != 0) {
2221 mbedtls_printf("passed\n");
2222 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002223 }
2224
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002225 if (verbose != 0) {
2226 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002227 }
2228
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002229 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002230 }
2231#endif /* MBEDTLS_CIPHER_MODE_XTS */
2232
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002233 ret = 0;
2234
2235exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002236 if (ret != 0 && verbose != 0) {
2237 mbedtls_printf("failed\n");
2238 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002239
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002240 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002241
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002242 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002243}
2244
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002245#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002246
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002247#endif /* MBEDTLS_AES_C */