blob: e4e4279e4a75778dcd3ac769d639a4b1fd4e1d46 [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
527static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
528{
529#if defined(MAY_NEED_TO_ALIGN)
530 int align_16_bytes = 0;
531
532#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
533 if (aes_padlock_ace == -1) {
534 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
535 }
536 if (aes_padlock_ace) {
537 align_16_bytes = 1;
538 }
539#endif
540
Gilles Peskine6dec5412023-03-16 17:21:33 +0100541#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskineb71d4022023-03-16 17:14:59 +0100542 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
543 align_16_bytes = 1;
544 }
545#endif
546
547 if (align_16_bytes) {
548 /* These implementations needs 16-byte alignment
549 * for the round key array. */
550 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
551 if (delta == 0) {
552 return 0;
553 } else {
554 return 4 - delta; // 16 bytes = 4 uint32_t
555 }
556 }
557#else /* MAY_NEED_TO_ALIGN */
558 (void) buf;
559#endif /* MAY_NEED_TO_ALIGN */
560
561 return 0;
562}
563
Paul Bakker5121ce52009-01-03 21:22:43 +0000564/*
565 * AES key schedule (encryption)
566 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200567#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100568int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
569 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000570{
Paul Bakker23986e52011-04-24 08:57:21 +0000571 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000572 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100574 AES_VALIDATE_RET(ctx != NULL);
575 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100577 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000578 case 128: ctx->nr = 10; break;
579 case 192: ctx->nr = 12; break;
580 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100581 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 }
583
Simon Butcher5201e412018-12-06 17:40:14 +0000584#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100585 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000586 aes_gen_tables();
587 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000588 }
589#endif
590
Gilles Peskineb71d4022023-03-16 17:14:59 +0100591 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000592
Gilles Peskine5511a342023-03-10 22:29:32 +0100593#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100594 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
595 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
596 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100597#endif
598
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100599 for (i = 0; i < (keybits >> 5); i++) {
600 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000601 }
602
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100603 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000604 case 10:
605
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100606 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000607 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100608 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
609 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
610 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
611 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
613 RK[5] = RK[1] ^ RK[4];
614 RK[6] = RK[2] ^ RK[5];
615 RK[7] = RK[3] ^ RK[6];
616 }
617 break;
618
619 case 12:
620
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100621 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000622 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100623 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
624 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
625 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
626 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
628 RK[7] = RK[1] ^ RK[6];
629 RK[8] = RK[2] ^ RK[7];
630 RK[9] = RK[3] ^ RK[8];
631 RK[10] = RK[4] ^ RK[9];
632 RK[11] = RK[5] ^ RK[10];
633 }
634 break;
635
636 case 14:
637
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100638 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000639 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100640 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
641 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
642 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
643 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
645 RK[9] = RK[1] ^ RK[8];
646 RK[10] = RK[2] ^ RK[9];
647 RK[11] = RK[3] ^ RK[10];
648
649 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100650 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
651 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
652 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
653 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
655 RK[13] = RK[5] ^ RK[12];
656 RK[14] = RK[6] ^ RK[13];
657 RK[15] = RK[7] ^ RK[14];
658 }
659 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000661
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100662 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000663}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200664#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000665
666/*
667 * AES key schedule (decryption)
668 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200669#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100670int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
671 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000672{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200673 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200674 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000675 uint32_t *RK;
676 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200677
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100678 AES_VALIDATE_RET(ctx != NULL);
679 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000680
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100681 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
Gilles Peskineb71d4022023-03-16 17:14:59 +0100683 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000684
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200685 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100686 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200687 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100688 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000689
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200690 ctx->nr = cty.nr;
691
Gilles Peskine5511a342023-03-10 22:29:32 +0100692#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100693 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
694 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
695 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200696 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100697 }
698#endif
699
Paul Bakker5121ce52009-01-03 21:22:43 +0000700 SK = cty.rk + cty.nr * 4;
701
702 *RK++ = *SK++;
703 *RK++ = *SK++;
704 *RK++ = *SK++;
705 *RK++ = *SK++;
706
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100707 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
708 for (j = 0; j < 4; j++, SK++) {
709 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
710 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
711 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
712 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000713 }
714 }
715
716 *RK++ = *SK++;
717 *RK++ = *SK++;
718 *RK++ = *SK++;
719 *RK++ = *SK++;
720
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200721exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100722 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000723
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100724 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000725}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100726#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100727
728#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100729static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
730 unsigned int keybits,
731 const unsigned char **key1,
732 unsigned int *key1bits,
733 const unsigned char **key2,
734 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100735{
736 const unsigned int half_keybits = keybits / 2;
737 const unsigned int half_keybytes = half_keybits / 8;
738
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100739 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100740 case 256: break;
741 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100742 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100743 }
744
745 *key1bits = half_keybits;
746 *key2bits = half_keybits;
747 *key1 = &key[0];
748 *key2 = &key[half_keybytes];
749
750 return 0;
751}
752
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100753int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
754 const unsigned char *key,
755 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100756{
Janos Follath24eed8d2019-11-22 13:21:35 +0000757 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100758 const unsigned char *key1, *key2;
759 unsigned int key1bits, key2bits;
760
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100761 AES_VALIDATE_RET(ctx != NULL);
762 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100763
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100764 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
765 &key2, &key2bits);
766 if (ret != 0) {
767 return ret;
768 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100769
770 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100771 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
772 if (ret != 0) {
773 return ret;
774 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100775
776 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100777 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100778}
779
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100780int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
781 const unsigned char *key,
782 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100783{
Janos Follath24eed8d2019-11-22 13:21:35 +0000784 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100785 const unsigned char *key1, *key2;
786 unsigned int key1bits, key2bits;
787
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100788 AES_VALIDATE_RET(ctx != NULL);
789 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100790
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100791 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
792 &key2, &key2bits);
793 if (ret != 0) {
794 return ret;
795 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100796
797 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100798 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
799 if (ret != 0) {
800 return ret;
801 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100802
803 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100804 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100805}
806#endif /* MBEDTLS_CIPHER_MODE_XTS */
807
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100808#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100809 do \
810 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100811 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
812 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
813 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
814 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100815 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100816 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
817 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
818 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
819 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100820 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100821 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
822 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
823 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
824 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100825 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100826 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
827 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
828 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
829 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
830 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000831
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100832#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100833 do \
834 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100835 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
836 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
837 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
838 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100839 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100840 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
841 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
842 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
843 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100844 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100845 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
846 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
847 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
848 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100849 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100850 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
851 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
852 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
853 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
854 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000855
856/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200857 * AES-ECB block encryption
858 */
859#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100860int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
861 const unsigned char input[16],
862 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200863{
864 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200865 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100866 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200867 uint32_t X[4];
868 uint32_t Y[4];
869 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200870
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100871 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
872 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
873 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
874 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200875
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100876 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
877 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]);
878 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 +0200879 }
880
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100881 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 +0200882
Gilles Peskine5197c662020-08-26 17:03:24 +0200883 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100884 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
885 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
886 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
887 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200888
Gilles Peskine5197c662020-08-26 17:03:24 +0200889 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100890 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
891 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
892 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
893 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200894
Gilles Peskine5197c662020-08-26 17:03:24 +0200895 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100896 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
897 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
898 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
899 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900
Gilles Peskine5197c662020-08-26 17:03:24 +0200901 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100902 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
903 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
904 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
905 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200906
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100907 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
908 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
909 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
910 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000911
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100912 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100914 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200915}
916#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
917
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100918#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100919void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
920 const unsigned char input[16],
921 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100922{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100923 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100924}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100925#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100926
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200927/*
928 * AES-ECB block decryption
929 */
930#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100931int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
932 const unsigned char input[16],
933 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934{
935 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200936 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100937 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200938 uint32_t X[4];
939 uint32_t Y[4];
940 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200941
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100942 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
943 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
944 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
945 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200946
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100947 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
948 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]);
949 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 +0200950 }
951
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100952 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 +0200953
Gilles Peskine5197c662020-08-26 17:03:24 +0200954 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100955 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
956 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
957 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
958 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200959
Gilles Peskine5197c662020-08-26 17:03:24 +0200960 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100961 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
962 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
963 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
964 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200965
Gilles Peskine5197c662020-08-26 17:03:24 +0200966 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100967 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
968 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
969 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
970 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200971
Gilles Peskine5197c662020-08-26 17:03:24 +0200972 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100973 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
974 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
975 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
976 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200977
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100978 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
979 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
980 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
981 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000982
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100983 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500984
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100985 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200986}
987#endif /* !MBEDTLS_AES_DECRYPT_ALT */
988
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100989#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100990void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
991 const unsigned char input[16],
992 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100993{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100994 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100995}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100996#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100997
Gilles Peskineb71d4022023-03-16 17:14:59 +0100998#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine6978e732023-03-16 13:08:42 +0100999/* VIA Padlock and our intrinsics-based implementation of AESNI require
1000 * the round keys to be aligned on a 16-byte boundary. We take care of this
1001 * before creating them, but the AES context may have moved (this can happen
1002 * if the library is called from a language with managed memory), and in later
1003 * calls it might have a different alignment with respect to 16-byte memory.
1004 * So we may need to realign.
1005 * NOTE: In the LTS branch, the context contains a pointer to within itself,
1006 * so if it has been moved, things will probably go pear-shaped. We keep this
1007 * code for compatibility with the development branch, in case of future changes.
1008 */
1009static void aes_maybe_realign(mbedtls_aes_context *ctx)
1010{
Tom Cosgrove2c942a32023-03-19 14:04:04 +00001011 unsigned current_offset = (unsigned) (ctx->rk - ctx->buf);
Gilles Peskineb71d4022023-03-16 17:14:59 +01001012 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1013 if (new_offset != current_offset) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001014 memmove(ctx->buf + new_offset, // new address
1015 ctx->buf + current_offset, // current address
1016 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1017 ctx->rk = ctx->buf + new_offset;
1018 }
1019}
1020#endif
1021
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001022/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001023 * AES-ECB block encryption/decryption
1024 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001025int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1026 int mode,
1027 const unsigned char input[16],
1028 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001029{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001030 AES_VALIDATE_RET(ctx != NULL);
1031 AES_VALIDATE_RET(input != NULL);
1032 AES_VALIDATE_RET(output != NULL);
1033 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1034 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001035
Gilles Peskineb71d4022023-03-16 17:14:59 +01001036#if defined(MAY_NEED_TO_ALIGN)
1037 aes_maybe_realign(ctx);
1038#endif
1039
Gilles Peskine5511a342023-03-10 22:29:32 +01001040#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001041 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1042 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1043 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001044#endif
1045
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001047 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001048 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001049 }
1050#endif
1051
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001052 if (mode == MBEDTLS_AES_ENCRYPT) {
1053 return mbedtls_internal_aes_encrypt(ctx, input, output);
1054 } else {
1055 return mbedtls_internal_aes_decrypt(ctx, input, output);
1056 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001057}
1058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001059#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001060/*
1061 * AES-CBC buffer encryption/decryption
1062 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001063int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1064 int mode,
1065 size_t length,
1066 unsigned char iv[16],
1067 const unsigned char *input,
1068 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001069{
1070 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001071 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001072 unsigned char temp[16];
1073
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001074 AES_VALIDATE_RET(ctx != NULL);
1075 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1076 mode == MBEDTLS_AES_DECRYPT);
1077 AES_VALIDATE_RET(iv != NULL);
1078 AES_VALIDATE_RET(input != NULL);
1079 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001080
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001081 if (length % 16) {
1082 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1083 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001084
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001086 if (aes_padlock_ace) {
1087 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1088 return 0;
1089 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001090
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001091 // If padlock data misaligned, we just fall back to
1092 // unaccelerated mode
1093 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001094 }
1095#endif
1096
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001097 if (mode == MBEDTLS_AES_DECRYPT) {
1098 while (length > 0) {
1099 memcpy(temp, input, 16);
1100 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1101 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001102 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001103 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001104
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001105 for (i = 0; i < 16; i++) {
1106 output[i] = (unsigned char) (output[i] ^ iv[i]);
1107 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001108
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001109 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001110
1111 input += 16;
1112 output += 16;
1113 length -= 16;
1114 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001115 } else {
1116 while (length > 0) {
1117 for (i = 0; i < 16; i++) {
1118 output[i] = (unsigned char) (input[i] ^ iv[i]);
1119 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001120
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001121 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1122 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001123 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001124 }
1125 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001126
1127 input += 16;
1128 output += 16;
1129 length -= 16;
1130 }
1131 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001132 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001133
Gilles Peskine377a3102021-07-07 21:08:28 +02001134exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001135 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001136}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001138
Aorimn5f778012016-06-09 23:22:58 +02001139#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001140
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001141typedef unsigned char mbedtls_be128[16];
1142
1143/*
1144 * GF(2^128) multiplication function
1145 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001146 * This function multiplies a field element by x in the polynomial field
1147 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001148 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001149 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001150 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001151static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1152 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001153{
1154 uint64_t a, b, ra, rb;
1155
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001156 a = MBEDTLS_GET_UINT64_LE(x, 0);
1157 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001159 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1160 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001161
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001162 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1163 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001164}
1165
Aorimn5f778012016-06-09 23:22:58 +02001166/*
1167 * AES-XTS buffer encryption/decryption
1168 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001169int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1170 int mode,
1171 size_t length,
1172 const unsigned char data_unit[16],
1173 const unsigned char *input,
1174 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001175{
Janos Follath24eed8d2019-11-22 13:21:35 +00001176 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001177 size_t blocks = length / 16;
1178 size_t leftover = length % 16;
1179 unsigned char tweak[16];
1180 unsigned char prev_tweak[16];
1181 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001182
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001183 AES_VALIDATE_RET(ctx != NULL);
1184 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1185 mode == MBEDTLS_AES_DECRYPT);
1186 AES_VALIDATE_RET(data_unit != NULL);
1187 AES_VALIDATE_RET(input != NULL);
1188 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001189
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001190 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001191 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001192 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001193 }
Aorimn5f778012016-06-09 23:22:58 +02001194
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001195 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001196 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001197 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001198 }
Aorimn5f778012016-06-09 23:22:58 +02001199
Jaeden Amerod82cd862018-04-28 15:02:45 +01001200 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001201 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1202 data_unit, tweak);
1203 if (ret != 0) {
1204 return ret;
1205 }
Aorimn5f778012016-06-09 23:22:58 +02001206
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001207 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001208 size_t i;
1209
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001210 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001211 /* We are on the last block in a decrypt operation that has
1212 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001213 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001214 * the leftovers and then update the current tweak for use on this,
1215 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001216 memcpy(prev_tweak, tweak, sizeof(tweak));
1217 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001218 }
1219
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001220 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001222 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001223
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001224 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1225 if (ret != 0) {
1226 return ret;
1227 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001228
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001229 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001230 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001231 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001232
1233 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001234 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235
1236 output += 16;
1237 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001238 }
1239
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001240 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241 /* If we are on the leftover bytes in a decrypt operation, we need to
1242 * use the previous tweak for these bytes (as saved in prev_tweak). */
1243 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001244
Jaeden Amerod82cd862018-04-28 15:02:45 +01001245 /* We are now on the final part of the data unit, which doesn't divide
1246 * evenly by 16. It's time for ciphertext stealing. */
1247 size_t i;
1248 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001249
Jaeden Amerod82cd862018-04-28 15:02:45 +01001250 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001251 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252 * remainder of the input for this final round (since the loop bounds
1253 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001254 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001255 output[i] = prev_output[i];
1256 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001257 }
Aorimn5f778012016-06-09 23:22:58 +02001258
Jaeden Amerod82cd862018-04-28 15:02:45 +01001259 /* Copy ciphertext bytes from the previous block for input in this
1260 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001261 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001263 }
Aorimn5f778012016-06-09 23:22:58 +02001264
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001265 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1266 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001267 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001268 }
Aorimn5f778012016-06-09 23:22:58 +02001269
Jaeden Amerod82cd862018-04-28 15:02:45 +01001270 /* Write the result back to the previous block, overriding the previous
1271 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001272 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001273 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001274 }
Aorimn5f778012016-06-09 23:22:58 +02001275 }
1276
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001277 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001278}
1279#endif /* MBEDTLS_CIPHER_MODE_XTS */
1280
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001281#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001282/*
1283 * AES-CFB128 buffer encryption/decryption
1284 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001285int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1286 int mode,
1287 size_t length,
1288 size_t *iv_off,
1289 unsigned char iv[16],
1290 const unsigned char *input,
1291 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001292{
Paul Bakker27fdf462011-06-09 13:55:13 +00001293 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001294 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001295 size_t n;
1296
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001297 AES_VALIDATE_RET(ctx != NULL);
1298 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1299 mode == MBEDTLS_AES_DECRYPT);
1300 AES_VALIDATE_RET(iv_off != NULL);
1301 AES_VALIDATE_RET(iv != NULL);
1302 AES_VALIDATE_RET(input != NULL);
1303 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001304
1305 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001306
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001307 if (n > 15) {
1308 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1309 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001310
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001311 if (mode == MBEDTLS_AES_DECRYPT) {
1312 while (length--) {
1313 if (n == 0) {
1314 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1315 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001316 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001317 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001318 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001319
1320 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001321 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001322 iv[n] = (unsigned char) c;
1323
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001324 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001325 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001326 } else {
1327 while (length--) {
1328 if (n == 0) {
1329 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1330 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001331 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001332 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001333 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001334
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001335 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001336
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001337 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 }
1339 }
1340
1341 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001342 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001343
Gilles Peskine377a3102021-07-07 21:08:28 +02001344exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001345 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001346}
Paul Bakker556efba2014-01-24 15:38:12 +01001347
1348/*
1349 * AES-CFB8 buffer encryption/decryption
1350 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001351int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1352 int mode,
1353 size_t length,
1354 unsigned char iv[16],
1355 const unsigned char *input,
1356 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001357{
Gilles Peskine377a3102021-07-07 21:08:28 +02001358 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001359 unsigned char c;
1360 unsigned char ov[17];
1361
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001362 AES_VALIDATE_RET(ctx != NULL);
1363 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1364 mode == MBEDTLS_AES_DECRYPT);
1365 AES_VALIDATE_RET(iv != NULL);
1366 AES_VALIDATE_RET(input != NULL);
1367 AES_VALIDATE_RET(output != NULL);
1368 while (length--) {
1369 memcpy(ov, iv, 16);
1370 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1371 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001372 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001373 }
Paul Bakker556efba2014-01-24 15:38:12 +01001374
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001375 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001376 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001377 }
Paul Bakker556efba2014-01-24 15:38:12 +01001378
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001379 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001380
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001381 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001382 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001383 }
Paul Bakker556efba2014-01-24 15:38:12 +01001384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001385 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001386 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001387 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001388
Gilles Peskine377a3102021-07-07 21:08:28 +02001389exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001390 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001391}
Simon Butcher76a5b222018-04-22 22:57:27 +01001392#endif /* MBEDTLS_CIPHER_MODE_CFB */
1393
1394#if defined(MBEDTLS_CIPHER_MODE_OFB)
1395/*
1396 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1397 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001398int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1399 size_t length,
1400 size_t *iv_off,
1401 unsigned char iv[16],
1402 const unsigned char *input,
1403 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001404{
Simon Butcherad4e4932018-04-29 00:43:47 +01001405 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001406 size_t n;
1407
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001408 AES_VALIDATE_RET(ctx != NULL);
1409 AES_VALIDATE_RET(iv_off != NULL);
1410 AES_VALIDATE_RET(iv != NULL);
1411 AES_VALIDATE_RET(input != NULL);
1412 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001413
1414 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001415
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001416 if (n > 15) {
1417 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1418 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001419
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001420 while (length--) {
1421 if (n == 0) {
1422 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1423 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001424 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001425 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001426 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001427 *output++ = *input++ ^ iv[n];
1428
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001429 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001430 }
1431
1432 *iv_off = n;
1433
Simon Butcherad4e4932018-04-29 00:43:47 +01001434exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001435 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001436}
1437#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001438
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001439#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001440/*
1441 * AES-CTR buffer encryption/decryption
1442 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001443int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1444 size_t length,
1445 size_t *nc_off,
1446 unsigned char nonce_counter[16],
1447 unsigned char stream_block[16],
1448 const unsigned char *input,
1449 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001450{
Paul Bakker369e14b2012-04-18 14:16:09 +00001451 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001452 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001453 size_t n;
1454
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001455 AES_VALIDATE_RET(ctx != NULL);
1456 AES_VALIDATE_RET(nc_off != NULL);
1457 AES_VALIDATE_RET(nonce_counter != NULL);
1458 AES_VALIDATE_RET(stream_block != NULL);
1459 AES_VALIDATE_RET(input != NULL);
1460 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001461
1462 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001463
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001464 if (n > 0x0F) {
1465 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1466 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001467
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001468 while (length--) {
1469 if (n == 0) {
1470 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1471 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001472 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001473 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001474
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001475 for (i = 16; i > 0; i--) {
1476 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001477 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001478 }
1479 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001480 }
1481 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001482 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001484 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001485 }
1486
1487 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001488 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001489
Gilles Peskine377a3102021-07-07 21:08:28 +02001490exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001491 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001492}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001498/*
1499 * AES test vectors from:
1500 *
1501 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1502 */
1503static const unsigned char aes_test_ecb_dec[3][16] =
1504{
1505 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1506 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1507 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1508 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1509 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1510 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1511};
1512
1513static const unsigned char aes_test_ecb_enc[3][16] =
1514{
1515 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1516 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1517 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1518 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1519 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1520 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1521};
1522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001524static const unsigned char aes_test_cbc_dec[3][16] =
1525{
1526 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1527 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1528 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1529 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1530 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1531 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1532};
1533
1534static const unsigned char aes_test_cbc_enc[3][16] =
1535{
1536 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1537 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1538 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1539 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1540 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1541 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1542};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001543#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001544
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001545#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001546/*
1547 * AES-CFB128 test vectors from:
1548 *
1549 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1550 */
1551static const unsigned char aes_test_cfb128_key[3][32] =
1552{
1553 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1554 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1555 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1556 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1557 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1558 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1559 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1560 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1561 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1562};
1563
1564static const unsigned char aes_test_cfb128_iv[16] =
1565{
1566 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1567 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1568};
1569
1570static const unsigned char aes_test_cfb128_pt[64] =
1571{
1572 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1573 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1574 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1575 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1576 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1577 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1578 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1579 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1580};
1581
1582static const unsigned char aes_test_cfb128_ct[3][64] =
1583{
1584 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1585 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1586 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1587 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1588 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1589 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1590 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1591 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1592 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1593 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1594 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1595 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1596 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1597 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1598 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1599 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1600 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1601 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1602 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1603 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1604 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1605 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1606 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1607 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1608};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001609#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001610
Simon Butcherad4e4932018-04-29 00:43:47 +01001611#if defined(MBEDTLS_CIPHER_MODE_OFB)
1612/*
1613 * AES-OFB test vectors from:
1614 *
Simon Butcher5db13622018-06-04 22:11:25 +01001615 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001616 */
1617static const unsigned char aes_test_ofb_key[3][32] =
1618{
1619 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1620 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1621 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1622 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1623 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1624 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1625 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1626 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1627 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1628};
1629
1630static const unsigned char aes_test_ofb_iv[16] =
1631{
1632 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1633 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1634};
1635
1636static const unsigned char aes_test_ofb_pt[64] =
1637{
1638 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1639 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1640 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1641 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1642 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1643 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1644 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1645 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1646};
1647
1648static const unsigned char aes_test_ofb_ct[3][64] =
1649{
1650 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1651 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1652 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1653 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1654 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1655 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1656 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1657 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1658 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1659 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1660 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1661 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1662 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1663 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1664 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1665 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1666 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1667 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1668 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1669 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1670 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1671 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1672 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1673 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1674};
1675#endif /* MBEDTLS_CIPHER_MODE_OFB */
1676
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001677#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001678/*
1679 * AES-CTR test vectors from:
1680 *
1681 * http://www.faqs.org/rfcs/rfc3686.html
1682 */
1683
1684static const unsigned char aes_test_ctr_key[3][16] =
1685{
1686 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1687 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1688 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1689 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1690 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1691 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1692};
1693
1694static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1695{
1696 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1698 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1699 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1700 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1701 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1702};
1703
1704static const unsigned char aes_test_ctr_pt[3][48] =
1705{
1706 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1707 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1708
1709 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1710 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1711 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1712 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1713
1714 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1715 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1716 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1717 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1718 0x20, 0x21, 0x22, 0x23 }
1719};
1720
1721static const unsigned char aes_test_ctr_ct[3][48] =
1722{
1723 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1724 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1725 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1726 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1727 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1728 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1729 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1730 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1731 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1732 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1733 0x25, 0xB2, 0x07, 0x2F }
1734};
1735
1736static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001737{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001738#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001739
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001740#if defined(MBEDTLS_CIPHER_MODE_XTS)
1741/*
1742 * AES-XTS test vectors from:
1743 *
1744 * IEEE P1619/D16 Annex B
1745 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1746 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1747 */
1748static const unsigned char aes_test_xts_key[][32] =
1749{
1750 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1754 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1755 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1756 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1757 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1758 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1759 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1760 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1761 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1762};
1763
1764static const unsigned char aes_test_xts_pt32[][32] =
1765{
1766 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1769 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1770 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1771 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1772 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
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};
1779
1780static const unsigned char aes_test_xts_ct32[][32] =
1781{
1782 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1783 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1784 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1785 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1786 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1787 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1788 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1789 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1790 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1791 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1792 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1793 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1794};
1795
1796static const unsigned char aes_test_xts_data_unit[][16] =
1797{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001798 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1800 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1802 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001804};
1805
1806#endif /* MBEDTLS_CIPHER_MODE_XTS */
1807
Paul Bakker5121ce52009-01-03 21:22:43 +00001808/*
1809 * Checkup routine
1810 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001811int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001812{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001813 int ret = 0, i, j, u, mode;
1814 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001815 unsigned char key[32];
1816 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001817 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001818#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1819 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001820 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001821#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001822#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001823 unsigned char prv[16];
1824#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001825#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1826 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001827 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001828#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001829#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001830 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001831#endif
1832#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001833 unsigned char nonce_counter[16];
1834 unsigned char stream_block[16];
1835#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001836 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001837
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001838 memset(key, 0, 32);
1839 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001841 if (verbose != 0) {
1842#if defined(MBEDTLS_AES_ALT)
1843 mbedtls_printf(" AES note: alternative implementation.\n");
1844#else /* MBEDTLS_AES_ALT */
1845#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1846 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1847 mbedtls_printf(" AES note: using VIA Padlock.\n");
1848 } else
1849#endif
1850#if defined(MBEDTLS_AESNI_HAVE_CODE)
1851 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Tom Cosgrove20458c02023-03-18 14:48:49 +00001852 mbedtls_printf(" AES note: using AESNI via ");
1853#if MBEDTLS_AESNI_HAVE_CODE == 1
1854 mbedtls_printf("assembly");
1855#elif MBEDTLS_AESNI_HAVE_CODE == 2
1856 mbedtls_printf("intrinsics");
1857#else
1858 mbedtls_printf("(unknown)");
1859#endif
1860 mbedtls_printf(".\n");
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001861 } else
1862#endif
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001863 mbedtls_printf(" AES note: built-in implementation.\n");
1864#endif /* MBEDTLS_AES_ALT */
1865 }
1866
Paul Bakker5121ce52009-01-03 21:22:43 +00001867 /*
1868 * ECB mode
1869 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001870 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001871 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001872 keybits = 128 + u * 64;
1873 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001874
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001875 if (verbose != 0) {
1876 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1877 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001879
1880 memset(buf, 0, 16);
1881
1882 if (mode == MBEDTLS_AES_DECRYPT) {
1883 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1884 aes_tests = aes_test_ecb_dec[u];
1885 } else {
1886 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001887 aes_tests = aes_test_ecb_enc[u];
1888 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001889
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001890 /*
1891 * AES-192 is an optional feature that may be unavailable when
1892 * there is an alternative underlying implementation i.e. when
1893 * MBEDTLS_AES_ALT is defined.
1894 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001895 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1896 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001897 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001898 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001899 goto exit;
1900 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001902 for (j = 0; j < 10000; j++) {
1903 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1904 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001905 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001906 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001907 }
1908
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001909 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001910 ret = 1;
1911 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 }
1913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001914 if (verbose != 0) {
1915 mbedtls_printf("passed\n");
1916 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001917 }
1918
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001919 if (verbose != 0) {
1920 mbedtls_printf("\n");
1921 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001922
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001923#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001924 /*
1925 * CBC mode
1926 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001927 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001928 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001929 keybits = 128 + u * 64;
1930 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001931
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001932 if (verbose != 0) {
1933 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1934 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001935 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001936
1937 memset(iv, 0, 16);
1938 memset(prv, 0, 16);
1939 memset(buf, 0, 16);
1940
1941 if (mode == MBEDTLS_AES_DECRYPT) {
1942 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1943 aes_tests = aes_test_cbc_dec[u];
1944 } else {
1945 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001946 aes_tests = aes_test_cbc_enc[u];
1947 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001948
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001949 /*
1950 * AES-192 is an optional feature that may be unavailable when
1951 * there is an alternative underlying implementation i.e. when
1952 * MBEDTLS_AES_ALT is defined.
1953 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001954 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1955 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001956 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001957 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001958 goto exit;
1959 }
1960
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001961 for (j = 0; j < 10000; j++) {
1962 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001963 unsigned char tmp[16];
1964
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001965 memcpy(tmp, prv, 16);
1966 memcpy(prv, buf, 16);
1967 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001968 }
1969
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001970 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1971 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001972 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001973 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001974
1975 }
1976
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001977 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001978 ret = 1;
1979 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001980 }
1981
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001982 if (verbose != 0) {
1983 mbedtls_printf("passed\n");
1984 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001985 }
1986
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001987 if (verbose != 0) {
1988 mbedtls_printf("\n");
1989 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001990#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001991
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001992#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001993 /*
1994 * CFB128 mode
1995 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001996 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001997 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001998 keybits = 128 + u * 64;
1999 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002000
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002001 if (verbose != 0) {
2002 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2003 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2004 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002005
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002006 memcpy(iv, aes_test_cfb128_iv, 16);
2007 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002008
2009 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002010 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002011 /*
2012 * AES-192 is an optional feature that may be unavailable when
2013 * there is an alternative underlying implementation i.e. when
2014 * MBEDTLS_AES_ALT is defined.
2015 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002016 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2017 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002018 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002019 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002020 goto exit;
2021 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002022
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002023 if (mode == MBEDTLS_AES_DECRYPT) {
2024 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002025 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002026 } else {
2027 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002028 aes_tests = aes_test_cfb128_ct[u];
2029 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002030
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002031 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2032 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002033 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002034 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002035
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002036 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002037 ret = 1;
2038 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002039 }
2040
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002041 if (verbose != 0) {
2042 mbedtls_printf("passed\n");
2043 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002044 }
2045
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002046 if (verbose != 0) {
2047 mbedtls_printf("\n");
2048 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002049#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002050
Simon Butcherad4e4932018-04-29 00:43:47 +01002051#if defined(MBEDTLS_CIPHER_MODE_OFB)
2052 /*
2053 * OFB mode
2054 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002055 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002056 u = i >> 1;
2057 keybits = 128 + u * 64;
2058 mode = i & 1;
2059
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002060 if (verbose != 0) {
2061 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2062 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2063 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002064
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002065 memcpy(iv, aes_test_ofb_iv, 16);
2066 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002067
2068 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002069 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002070 /*
2071 * AES-192 is an optional feature that may be unavailable when
2072 * there is an alternative underlying implementation i.e. when
2073 * MBEDTLS_AES_ALT is defined.
2074 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002075 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2076 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002077 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002078 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002079 goto exit;
2080 }
2081
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002082 if (mode == MBEDTLS_AES_DECRYPT) {
2083 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002084 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002085 } else {
2086 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002087 aes_tests = aes_test_ofb_ct[u];
2088 }
2089
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002090 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2091 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002092 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002093 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002094
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002095 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002096 ret = 1;
2097 goto exit;
2098 }
2099
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002100 if (verbose != 0) {
2101 mbedtls_printf("passed\n");
2102 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002103 }
2104
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002105 if (verbose != 0) {
2106 mbedtls_printf("\n");
2107 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002108#endif /* MBEDTLS_CIPHER_MODE_OFB */
2109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002110#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002111 /*
2112 * CTR mode
2113 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002114 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002115 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002116 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002117
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002118 if (verbose != 0) {
2119 mbedtls_printf(" AES-CTR-128 (%s): ",
2120 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2121 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002122
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002123 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2124 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002125
2126 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002127 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002128 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002129 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002130
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002131 len = aes_test_ctr_len[u];
2132
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002133 if (mode == MBEDTLS_AES_DECRYPT) {
2134 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002135 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002136 } else {
2137 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002138 aes_tests = aes_test_ctr_ct[u];
2139 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002140
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002141 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2142 stream_block, buf, buf);
2143 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002144 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002145 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002146
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002147 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002148 ret = 1;
2149 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002150 }
2151
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002152 if (verbose != 0) {
2153 mbedtls_printf("passed\n");
2154 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002155 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002156
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002157 if (verbose != 0) {
2158 mbedtls_printf("\n");
2159 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002160#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002161
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002162#if defined(MBEDTLS_CIPHER_MODE_XTS)
2163 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002164 static const int num_tests =
2165 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2166 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002168 /*
2169 * XTS mode
2170 */
2171 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002172
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002173 for (i = 0; i < num_tests << 1; i++) {
2174 const unsigned char *data_unit;
2175 u = i >> 1;
2176 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002177
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002178 if (verbose != 0) {
2179 mbedtls_printf(" AES-XTS-128 (%s): ",
2180 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2181 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002182
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002183 memset(key, 0, sizeof(key));
2184 memcpy(key, aes_test_xts_key[u], 32);
2185 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002186
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002187 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002188
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002189 if (mode == MBEDTLS_AES_DECRYPT) {
2190 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2191 if (ret != 0) {
2192 goto exit;
2193 }
2194 memcpy(buf, aes_test_xts_ct32[u], len);
2195 aes_tests = aes_test_xts_pt32[u];
2196 } else {
2197 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2198 if (ret != 0) {
2199 goto exit;
2200 }
2201 memcpy(buf, aes_test_xts_pt32[u], len);
2202 aes_tests = aes_test_xts_ct32[u];
2203 }
2204
2205
2206 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2207 buf, buf);
2208 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002209 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002210 }
2211
2212 if (memcmp(buf, aes_tests, len) != 0) {
2213 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002214 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002215 }
2216
2217 if (verbose != 0) {
2218 mbedtls_printf("passed\n");
2219 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002220 }
2221
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002222 if (verbose != 0) {
2223 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002224 }
2225
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002226 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002227 }
2228#endif /* MBEDTLS_CIPHER_MODE_XTS */
2229
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002230 ret = 0;
2231
2232exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002233 if (ret != 0 && verbose != 0) {
2234 mbedtls_printf("failed\n");
2235 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002236
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002237 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002238
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002239 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002240}
2241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002242#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002244#endif /* MBEDTLS_AES_C */