blob: 5e0304d77a70cf8e513d57e6144dbb97f2ac34c0 [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
Dave Rodgmandbae1842023-06-27 18:27:31 +0100189#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000190/*
191 * Reverse S-box
192 */
193static const unsigned char RSb[256] =
194{
195 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
196 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
197 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
198 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
199 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
200 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
201 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
202 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
203 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
204 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
205 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
206 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
207 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
208 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
209 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
210 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
211 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
212 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
213 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
214 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
215 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
216 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
217 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
218 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
219 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
220 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
221 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
222 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
223 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
224 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
225 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
226 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
227};
Dave Rodgmandbae1842023-06-27 18:27:31 +0100228#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000229
230/*
231 * Reverse tables
232 */
233#define RT \
234\
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100235 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
236 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
237 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
238 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
239 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
240 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
241 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
242 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
243 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
244 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
245 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
246 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
247 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
248 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
249 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
250 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
251 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
252 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
253 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
254 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
255 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
256 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
257 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
258 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
259 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
260 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
261 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
262 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
263 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
264 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
265 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
266 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
267 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
268 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
269 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
270 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
271 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
272 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
273 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
274 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
275 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
276 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
277 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
278 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
279 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
280 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
281 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
282 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
283 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
284 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
285 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
286 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
287 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
288 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
289 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
290 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
291 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
292 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
293 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
294 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
295 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
296 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
297 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
298 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 +0000299
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000301static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000302#undef V
303
Hanno Beckerad049a92017-06-19 16:31:54 +0100304#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200305
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100306#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000311static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000312#undef V
313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100314#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000315static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000316#undef V
317
Hanno Becker177d3cf2017-06-07 15:52:48 +0100318#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200319
Paul Bakker5121ce52009-01-03 21:22:43 +0000320#undef RT
321
322/*
323 * Round constants
324 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000325static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000326{
327 0x00000001, 0x00000002, 0x00000004, 0x00000008,
328 0x00000010, 0x00000020, 0x00000040, 0x00000080,
329 0x0000001B, 0x00000036
330};
331
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000333
334/*
335 * Forward S-box & tables
336 */
337static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200338static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100339#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200340static uint32_t FT1[256];
341static uint32_t FT2[256];
342static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100343#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000344
345/*
346 * Reverse S-box & tables
347 */
Dave Rodgmandbae1842023-06-27 18:27:31 +0100348#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000349static unsigned char RSb[256];
Dave Rodgmandbae1842023-06-27 18:27:31 +0100350#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100352#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000353static uint32_t RT1[256];
354static uint32_t RT2[256];
355static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100356#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100358#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000359/*
360 * Round constants
361 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000362static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
364/*
365 * Tables generation code
366 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100367#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
368#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
369#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000370
371static int aes_init_done = 0;
372
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100373static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000374{
375 int i, x, y, z;
376 int pow[256];
377 int log[256];
378
379 /*
380 * compute pow and log tables over GF(2^8)
381 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100382 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 pow[i] = x;
384 log[x] = i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000386 }
387
388 /*
389 * calculate the round constants
390 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100391 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000392 RCON[i] = (uint32_t) x;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100393 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 }
395
396 /*
397 * generate the forward and reverse S-boxes
398 */
399 FSb[0x00] = 0x63;
400 RSb[0x63] = 0x00;
401
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100402 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 x = pow[255 - log[i]];
404
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100405 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
406 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
407 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
408 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000409 x ^= y ^ 0x63;
410
411 FSb[i] = (unsigned char) x;
412 RSb[x] = (unsigned char) i;
413 }
414
415 /*
416 * generate the forward and reverse tables
417 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100418 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 x = FSb[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100420 y = MBEDTLS_BYTE_0(XTIME(x));
421 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100423 FT0[i] = ((uint32_t) y) ^
424 ((uint32_t) x << 8) ^
425 ((uint32_t) x << 16) ^
426 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
Hanno Beckerad049a92017-06-19 16:31:54 +0100428#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100429 FT1[i] = ROTL8(FT0[i]);
430 FT2[i] = ROTL8(FT1[i]);
431 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100432#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
434 x = RSb[i];
435
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100436 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
437 ((uint32_t) MUL(0x09, x) << 8) ^
438 ((uint32_t) MUL(0x0D, x) << 16) ^
439 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Hanno Beckerad049a92017-06-19 16:31:54 +0100441#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100442 RT1[i] = ROTL8(RT0[i]);
443 RT2[i] = ROTL8(RT1[i]);
444 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100445#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 }
447}
448
Dave Rodgman1e6f7702023-06-27 18:16:13 +0100449#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
450
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200451#undef ROTL8
452
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
Hanno Beckerad049a92017-06-19 16:31:54 +0100455#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100457#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
458#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
459#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200460
461#define AES_RT0(idx) RT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100462#define AES_RT1(idx) ROTL8(RT0[idx])
463#define AES_RT2(idx) ROTL16(RT0[idx])
464#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200465
466#define AES_FT0(idx) FT0[idx]
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100467#define AES_FT1(idx) ROTL8(FT0[idx])
468#define AES_FT2(idx) ROTL16(FT0[idx])
469#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200470
Hanno Becker177d3cf2017-06-07 15:52:48 +0100471#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472
473#define AES_RT0(idx) RT0[idx]
474#define AES_RT1(idx) RT1[idx]
475#define AES_RT2(idx) RT2[idx]
476#define AES_RT3(idx) RT3[idx]
477
478#define AES_FT0(idx) FT0[idx]
479#define AES_FT1(idx) FT1[idx]
480#define AES_FT2(idx) FT2[idx]
481#define AES_FT3(idx) FT3[idx]
482
Hanno Becker177d3cf2017-06-07 15:52:48 +0100483#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200484
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100485void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200486{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000488
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100489 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200490}
491
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100492void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200493{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100494 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200495 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100496 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200497
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100498 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200499}
500
Jaeden Amero9366feb2018-05-29 18:55:17 +0100501#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100503{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100504 AES_VALIDATE(ctx != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000505
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100506 mbedtls_aes_init(&ctx->crypt);
507 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100508}
509
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100510void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100511{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100512 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100513 return;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100514 }
Simon Butcher5201e412018-12-06 17:40:14 +0000515
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100516 mbedtls_aes_free(&ctx->crypt);
517 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100518}
519#endif /* MBEDTLS_CIPHER_MODE_XTS */
520
Gilles Peskineb71d4022023-03-16 17:14:59 +0100521/* Some implementations need the round keys to be aligned.
522 * Return an offset to be added to buf, such that (buf + offset) is
523 * correctly aligned.
524 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
525 * i.e. an offset of 1 means 4 bytes and so on.
526 */
527#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine6dec5412023-03-16 17:21:33 +0100528 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100529#define MAY_NEED_TO_ALIGN
530#endif
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100531
532#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskineb71d4022023-03-16 17:14:59 +0100533static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
534{
535#if defined(MAY_NEED_TO_ALIGN)
536 int align_16_bytes = 0;
537
538#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
539 if (aes_padlock_ace == -1) {
540 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
541 }
542 if (aes_padlock_ace) {
543 align_16_bytes = 1;
544 }
545#endif
546
Gilles Peskine6dec5412023-03-16 17:21:33 +0100547#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskineb71d4022023-03-16 17:14:59 +0100548 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
549 align_16_bytes = 1;
550 }
551#endif
552
553 if (align_16_bytes) {
554 /* These implementations needs 16-byte alignment
555 * for the round key array. */
556 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
557 if (delta == 0) {
558 return 0;
559 } else {
560 return 4 - delta; // 16 bytes = 4 uint32_t
561 }
562 }
563#else /* MAY_NEED_TO_ALIGN */
564 (void) buf;
565#endif /* MAY_NEED_TO_ALIGN */
566
567 return 0;
568}
Dave Rodgman9b20aea2023-06-27 18:22:34 +0100569#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskineb71d4022023-03-16 17:14:59 +0100570
Paul Bakker5121ce52009-01-03 21:22:43 +0000571/*
572 * AES key schedule (encryption)
573 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200574#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100575int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
576 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000577{
Paul Bakker23986e52011-04-24 08:57:21 +0000578 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000579 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100581 AES_VALIDATE_RET(ctx != NULL);
582 AES_VALIDATE_RET(key != NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100584 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000585 case 128: ctx->nr = 10; break;
586 case 192: ctx->nr = 12; break;
587 case 256: ctx->nr = 14; break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100588 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 }
590
Simon Butcher5201e412018-12-06 17:40:14 +0000591#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100592 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000593 aes_gen_tables();
594 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000595 }
596#endif
597
Gilles Peskineb71d4022023-03-16 17:14:59 +0100598 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Gilles Peskine5511a342023-03-10 22:29:32 +0100600#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100601 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
602 return mbedtls_aesni_setkey_enc((unsigned char *) ctx->rk, key, keybits);
603 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100604#endif
605
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100606 for (i = 0; i < (keybits >> 5); i++) {
607 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
609
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100610 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000611 case 10:
612
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100613 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000614 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100615 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
616 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
617 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
618 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
620 RK[5] = RK[1] ^ RK[4];
621 RK[6] = RK[2] ^ RK[5];
622 RK[7] = RK[3] ^ RK[6];
623 }
624 break;
625
626 case 12:
627
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100628 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100630 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
631 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
632 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
633 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 RK[7] = RK[1] ^ RK[6];
636 RK[8] = RK[2] ^ RK[7];
637 RK[9] = RK[3] ^ RK[8];
638 RK[10] = RK[4] ^ RK[9];
639 RK[11] = RK[5] ^ RK[10];
640 }
641 break;
642
643 case 14:
644
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100645 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100647 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
648 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
649 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
650 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
652 RK[9] = RK[1] ^ RK[8];
653 RK[10] = RK[2] ^ RK[9];
654 RK[11] = RK[3] ^ RK[10];
655
656 RK[12] = RK[4] ^
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100657 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
658 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
659 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
660 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662 RK[13] = RK[5] ^ RK[12];
663 RK[14] = RK[6] ^ RK[13];
664 RK[15] = RK[7] ^ RK[14];
665 }
666 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000667 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000668
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100669 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000670}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200671#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000672
673/*
674 * AES key schedule (decryption)
675 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200676#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100677int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
678 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000679{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200680 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200681 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000682 uint32_t *RK;
683 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200684
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100685 AES_VALIDATE_RET(ctx != NULL);
686 AES_VALIDATE_RET(key != NULL);
Simon Butcher5201e412018-12-06 17:40:14 +0000687
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100688 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000689
Gilles Peskineb71d4022023-03-16 17:14:59 +0100690 ctx->rk = RK = ctx->buf + mbedtls_aes_rk_offset(ctx->buf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200692 /* Also checks keybits */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100693 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200694 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100695 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000696
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200697 ctx->nr = cty.nr;
698
Gilles Peskine5511a342023-03-10 22:29:32 +0100699#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100700 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
701 mbedtls_aesni_inverse_key((unsigned char *) ctx->rk,
702 (const unsigned char *) cty.rk, ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200703 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100704 }
705#endif
706
Paul Bakker5121ce52009-01-03 21:22:43 +0000707 SK = cty.rk + cty.nr * 4;
708
709 *RK++ = *SK++;
710 *RK++ = *SK++;
711 *RK++ = *SK++;
712 *RK++ = *SK++;
713
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100714 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
715 for (j = 0; j < 4; j++, SK++) {
716 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
717 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
718 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
719 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000720 }
721 }
722
723 *RK++ = *SK++;
724 *RK++ = *SK++;
725 *RK++ = *SK++;
726 *RK++ = *SK++;
727
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200728exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100729 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000730
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100731 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000732}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100733#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100734
735#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100736static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
737 unsigned int keybits,
738 const unsigned char **key1,
739 unsigned int *key1bits,
740 const unsigned char **key2,
741 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100742{
743 const unsigned int half_keybits = keybits / 2;
744 const unsigned int half_keybytes = half_keybits / 8;
745
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100746 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100747 case 256: break;
748 case 512: break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100749 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100750 }
751
752 *key1bits = half_keybits;
753 *key2bits = half_keybits;
754 *key1 = &key[0];
755 *key2 = &key[half_keybytes];
756
757 return 0;
758}
759
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100760int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
761 const unsigned char *key,
762 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100763{
Janos Follath24eed8d2019-11-22 13:21:35 +0000764 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100765 const unsigned char *key1, *key2;
766 unsigned int key1bits, key2bits;
767
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100768 AES_VALIDATE_RET(ctx != NULL);
769 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100770
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100771 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
772 &key2, &key2bits);
773 if (ret != 0) {
774 return ret;
775 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100776
777 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100778 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
779 if (ret != 0) {
780 return ret;
781 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100782
783 /* Set crypt key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100784 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100785}
786
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100787int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
788 const unsigned char *key,
789 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100790{
Janos Follath24eed8d2019-11-22 13:21:35 +0000791 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100792 const unsigned char *key1, *key2;
793 unsigned int key1bits, key2bits;
794
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100795 AES_VALIDATE_RET(ctx != NULL);
796 AES_VALIDATE_RET(key != NULL);
Manuel Pégourié-Gonnard68e3dff2018-12-12 12:48:04 +0100797
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100798 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
799 &key2, &key2bits);
800 if (ret != 0) {
801 return ret;
802 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100803
804 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100805 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
806 if (ret != 0) {
807 return ret;
808 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100809
810 /* Set crypt key for decryption. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100811 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100812}
813#endif /* MBEDTLS_CIPHER_MODE_XTS */
814
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100815#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100816 do \
817 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100818 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
819 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
820 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
821 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100822 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100823 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
824 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
825 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
826 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100827 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100828 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
829 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
830 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
831 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbiani6b897c92021-07-08 14:59:52 +0100832 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100833 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
834 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
835 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
836 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
837 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100839#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100840 do \
841 { \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100842 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
843 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
844 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
845 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100846 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100847 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
848 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
849 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
850 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100851 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100852 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
853 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
854 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
855 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100856 \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100857 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
858 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
859 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
860 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
861 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
863/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200864 * AES-ECB block encryption
865 */
866#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100867int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
868 const unsigned char input[16],
869 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200870{
871 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200872 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100873 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200874 uint32_t X[4];
875 uint32_t Y[4];
876 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200877
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100878 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
879 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
880 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
881 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200882
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100883 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
884 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]);
885 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 +0200886 }
887
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100888 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 +0200889
Gilles Peskine5197c662020-08-26 17:03:24 +0200890 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100891 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
892 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
893 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
894 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200895
Gilles Peskine5197c662020-08-26 17:03:24 +0200896 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100897 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
898 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
899 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
900 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200901
Gilles Peskine5197c662020-08-26 17:03:24 +0200902 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100903 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
904 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
905 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
906 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200907
Gilles Peskine5197c662020-08-26 17:03:24 +0200908 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100909 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
910 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
911 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
912 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100914 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
915 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
916 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
917 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000918
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100919 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500920
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100921 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200922}
923#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
924
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100925#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100926void mbedtls_aes_encrypt(mbedtls_aes_context *ctx,
927 const unsigned char input[16],
928 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +0100929{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100930 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_encrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +0100931}
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100932#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +0100933
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934/*
935 * AES-ECB block decryption
936 */
937#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100938int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
939 const unsigned char input[16],
940 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200941{
942 int i;
Gilles Peskine5197c662020-08-26 17:03:24 +0200943 uint32_t *RK = ctx->rk;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100944 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200945 uint32_t X[4];
946 uint32_t Y[4];
947 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200948
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100949 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
950 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
951 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
952 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200953
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100954 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
955 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]);
956 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 +0200957 }
958
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100959 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 +0200960
Gilles Peskine5197c662020-08-26 17:03:24 +0200961 t.X[0] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100962 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
963 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
964 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
965 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200966
Gilles Peskine5197c662020-08-26 17:03:24 +0200967 t.X[1] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100968 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
969 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
970 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
971 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200972
Gilles Peskine5197c662020-08-26 17:03:24 +0200973 t.X[2] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100974 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
975 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
976 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200978
Gilles Peskine5197c662020-08-26 17:03:24 +0200979 t.X[3] = *RK++ ^ \
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100980 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
981 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
982 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200984
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100985 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
986 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
987 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
988 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000989
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100990 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500991
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100992 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200993}
994#endif /* !MBEDTLS_AES_DECRYPT_ALT */
995
Gilles Peskine8db3efb2018-02-21 19:16:20 +0100996#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100997void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
998 const unsigned char input[16],
999 unsigned char output[16])
Hanno Beckerbedc2052017-06-26 12:46:56 +01001000{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001001 MBEDTLS_IGNORE_RETURN(mbedtls_internal_aes_decrypt(ctx, input, output));
Hanno Beckerbedc2052017-06-26 12:46:56 +01001002}
Gilles Peskine8db3efb2018-02-21 19:16:20 +01001003#endif /* !MBEDTLS_DEPRECATED_REMOVED */
Hanno Beckerbedc2052017-06-26 12:46:56 +01001004
Gilles Peskineb71d4022023-03-16 17:14:59 +01001005#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine6978e732023-03-16 13:08:42 +01001006/* VIA Padlock and our intrinsics-based implementation of AESNI require
1007 * the round keys to be aligned on a 16-byte boundary. We take care of this
1008 * before creating them, but the AES context may have moved (this can happen
1009 * if the library is called from a language with managed memory), and in later
1010 * calls it might have a different alignment with respect to 16-byte memory.
1011 * So we may need to realign.
1012 * NOTE: In the LTS branch, the context contains a pointer to within itself,
1013 * so if it has been moved, things will probably go pear-shaped. We keep this
1014 * code for compatibility with the development branch, in case of future changes.
1015 */
1016static void aes_maybe_realign(mbedtls_aes_context *ctx)
1017{
Tom Cosgrove2c942a32023-03-19 14:04:04 +00001018 unsigned current_offset = (unsigned) (ctx->rk - ctx->buf);
Gilles Peskineb71d4022023-03-16 17:14:59 +01001019 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1020 if (new_offset != current_offset) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001021 memmove(ctx->buf + new_offset, // new address
1022 ctx->buf + current_offset, // current address
1023 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1024 ctx->rk = ctx->buf + new_offset;
1025 }
1026}
1027#endif
1028
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001029/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001030 * AES-ECB block encryption/decryption
1031 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001032int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1033 int mode,
1034 const unsigned char input[16],
1035 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001036{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001037 AES_VALIDATE_RET(ctx != NULL);
1038 AES_VALIDATE_RET(input != NULL);
1039 AES_VALIDATE_RET(output != NULL);
1040 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1041 mode == MBEDTLS_AES_DECRYPT);
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001042
Gilles Peskineb71d4022023-03-16 17:14:59 +01001043#if defined(MAY_NEED_TO_ALIGN)
1044 aes_maybe_realign(ctx);
1045#endif
1046
Gilles Peskine5511a342023-03-10 22:29:32 +01001047#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001048 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1049 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1050 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001051#endif
1052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001054 if (aes_padlock_ace) {
Gilles Peskine6978e732023-03-16 13:08:42 +01001055 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001056 }
1057#endif
1058
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001059 if (mode == MBEDTLS_AES_ENCRYPT) {
1060 return mbedtls_internal_aes_encrypt(ctx, input, output);
1061 } else {
1062 return mbedtls_internal_aes_decrypt(ctx, input, output);
1063 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001064}
1065
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001067/*
1068 * AES-CBC buffer encryption/decryption
1069 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001070int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1071 int mode,
1072 size_t length,
1073 unsigned char iv[16],
1074 const unsigned char *input,
1075 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001076{
1077 int i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001078 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001079 unsigned char temp[16];
1080
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001081 AES_VALIDATE_RET(ctx != NULL);
1082 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1083 mode == MBEDTLS_AES_DECRYPT);
1084 AES_VALIDATE_RET(iv != NULL);
1085 AES_VALIDATE_RET(input != NULL);
1086 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001087
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001088 if (length % 16) {
1089 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1090 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001091
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001092#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001093 if (aes_padlock_ace) {
1094 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1095 return 0;
1096 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001097
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001098 // If padlock data misaligned, we just fall back to
1099 // unaccelerated mode
1100 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001101 }
1102#endif
1103
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001104 if (mode == MBEDTLS_AES_DECRYPT) {
1105 while (length > 0) {
1106 memcpy(temp, input, 16);
1107 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1108 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001109 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001110 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001111
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001112 for (i = 0; i < 16; i++) {
1113 output[i] = (unsigned char) (output[i] ^ iv[i]);
1114 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001115
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001116 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001117
1118 input += 16;
1119 output += 16;
1120 length -= 16;
1121 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001122 } else {
1123 while (length > 0) {
1124 for (i = 0; i < 16; i++) {
1125 output[i] = (unsigned char) (input[i] ^ iv[i]);
1126 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001127
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001128 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1129 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001130 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001131 }
1132 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001133
1134 input += 16;
1135 output += 16;
1136 length -= 16;
1137 }
1138 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001139 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001140
Gilles Peskine377a3102021-07-07 21:08:28 +02001141exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001142 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001143}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001145
Aorimn5f778012016-06-09 23:22:58 +02001146#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001147
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001148typedef unsigned char mbedtls_be128[16];
1149
1150/*
1151 * GF(2^128) multiplication function
1152 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001153 * This function multiplies a field element by x in the polynomial field
1154 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case0e7791f2021-12-20 21:14:10 -08001155 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001156 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001157 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001158static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1159 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001160{
1161 uint64_t a, b, ra, rb;
1162
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001163 a = MBEDTLS_GET_UINT64_LE(x, 0);
1164 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001165
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001166 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1167 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001168
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001169 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1170 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001171}
1172
Aorimn5f778012016-06-09 23:22:58 +02001173/*
1174 * AES-XTS buffer encryption/decryption
1175 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001176int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1177 int mode,
1178 size_t length,
1179 const unsigned char data_unit[16],
1180 const unsigned char *input,
1181 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001182{
Janos Follath24eed8d2019-11-22 13:21:35 +00001183 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001184 size_t blocks = length / 16;
1185 size_t leftover = length % 16;
1186 unsigned char tweak[16];
1187 unsigned char prev_tweak[16];
1188 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001189
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001190 AES_VALIDATE_RET(ctx != NULL);
1191 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1192 mode == MBEDTLS_AES_DECRYPT);
1193 AES_VALIDATE_RET(data_unit != NULL);
1194 AES_VALIDATE_RET(input != NULL);
1195 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001196
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001197 /* Data units must be at least 16 bytes long. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001198 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001199 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001200 }
Aorimn5f778012016-06-09 23:22:58 +02001201
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001202 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001203 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001204 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001205 }
Aorimn5f778012016-06-09 23:22:58 +02001206
Jaeden Amerod82cd862018-04-28 15:02:45 +01001207 /* Compute the tweak. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001208 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1209 data_unit, tweak);
1210 if (ret != 0) {
1211 return ret;
1212 }
Aorimn5f778012016-06-09 23:22:58 +02001213
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001214 while (blocks--) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001215 size_t i;
1216
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001217 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001218 /* We are on the last block in a decrypt operation that has
1219 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove49f99bc2022-12-04 16:44:21 +00001220 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 * the leftovers and then update the current tweak for use on this,
1222 * the last full block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001223 memcpy(prev_tweak, tweak, sizeof(tweak));
1224 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001225 }
1226
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001227 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001228 tmp[i] = input[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001229 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001230
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001231 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1232 if (ret != 0) {
1233 return ret;
1234 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001236 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001237 output[i] = tmp[i] ^ tweak[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001238 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001239
1240 /* Update the tweak for the next block. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001241 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001242
1243 output += 16;
1244 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001245 }
1246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001247 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001248 /* If we are on the leftover bytes in a decrypt operation, we need to
1249 * use the previous tweak for these bytes (as saved in prev_tweak). */
1250 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001251
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252 /* We are now on the final part of the data unit, which doesn't divide
1253 * evenly by 16. It's time for ciphertext stealing. */
1254 size_t i;
1255 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001256
Jaeden Amerod82cd862018-04-28 15:02:45 +01001257 /* Copy ciphertext bytes from the previous block to our output for each
Shaun Case0e7791f2021-12-20 21:14:10 -08001258 * byte of ciphertext we won't steal. At the same time, copy the
Jaeden Amerod82cd862018-04-28 15:02:45 +01001259 * remainder of the input for this final round (since the loop bounds
1260 * are the same). */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001261 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 output[i] = prev_output[i];
1263 tmp[i] = input[i] ^ t[i];
Aorimn5f778012016-06-09 23:22:58 +02001264 }
Aorimn5f778012016-06-09 23:22:58 +02001265
Jaeden Amerod82cd862018-04-28 15:02:45 +01001266 /* Copy ciphertext bytes from the previous block for input in this
1267 * round. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001268 for (; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001269 tmp[i] = prev_output[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001270 }
Aorimn5f778012016-06-09 23:22:58 +02001271
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001272 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1273 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 return ret;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001275 }
Aorimn5f778012016-06-09 23:22:58 +02001276
Jaeden Amerod82cd862018-04-28 15:02:45 +01001277 /* Write the result back to the previous block, overriding the previous
1278 * output we copied. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001279 for (i = 0; i < 16; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001280 prev_output[i] = tmp[i] ^ t[i];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001281 }
Aorimn5f778012016-06-09 23:22:58 +02001282 }
1283
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001284 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001285}
1286#endif /* MBEDTLS_CIPHER_MODE_XTS */
1287
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001288#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001289/*
1290 * AES-CFB128 buffer encryption/decryption
1291 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001292int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1293 int mode,
1294 size_t length,
1295 size_t *iv_off,
1296 unsigned char iv[16],
1297 const unsigned char *input,
1298 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001299{
Paul Bakker27fdf462011-06-09 13:55:13 +00001300 int c;
Gilles Peskine377a3102021-07-07 21:08:28 +02001301 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001302 size_t n;
1303
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001304 AES_VALIDATE_RET(ctx != NULL);
1305 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1306 mode == MBEDTLS_AES_DECRYPT);
1307 AES_VALIDATE_RET(iv_off != NULL);
1308 AES_VALIDATE_RET(iv != NULL);
1309 AES_VALIDATE_RET(input != NULL);
1310 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001311
1312 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001313
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001314 if (n > 15) {
1315 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1316 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001317
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001318 if (mode == MBEDTLS_AES_DECRYPT) {
1319 while (length--) {
1320 if (n == 0) {
1321 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1322 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001323 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001324 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001325 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001326
1327 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001328 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001329 iv[n] = (unsigned char) c;
1330
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001331 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001332 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001333 } else {
1334 while (length--) {
1335 if (n == 0) {
1336 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1337 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001338 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001339 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001340 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001341
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001342 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001343
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001344 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001345 }
1346 }
1347
1348 *iv_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001349 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001350
Gilles Peskine377a3102021-07-07 21:08:28 +02001351exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001352 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001353}
Paul Bakker556efba2014-01-24 15:38:12 +01001354
1355/*
1356 * AES-CFB8 buffer encryption/decryption
1357 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001358int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1359 int mode,
1360 size_t length,
1361 unsigned char iv[16],
1362 const unsigned char *input,
1363 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001364{
Gilles Peskine377a3102021-07-07 21:08:28 +02001365 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001366 unsigned char c;
1367 unsigned char ov[17];
1368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001369 AES_VALIDATE_RET(ctx != NULL);
1370 AES_VALIDATE_RET(mode == MBEDTLS_AES_ENCRYPT ||
1371 mode == MBEDTLS_AES_DECRYPT);
1372 AES_VALIDATE_RET(iv != NULL);
1373 AES_VALIDATE_RET(input != NULL);
1374 AES_VALIDATE_RET(output != NULL);
1375 while (length--) {
1376 memcpy(ov, iv, 16);
1377 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1378 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001379 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001380 }
Paul Bakker556efba2014-01-24 15:38:12 +01001381
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001382 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001383 ov[16] = *input;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001384 }
Paul Bakker556efba2014-01-24 15:38:12 +01001385
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001386 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001387
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001388 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001389 ov[16] = c;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001390 }
Paul Bakker556efba2014-01-24 15:38:12 +01001391
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001392 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001393 }
Gilles Peskine377a3102021-07-07 21:08:28 +02001394 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001395
Gilles Peskine377a3102021-07-07 21:08:28 +02001396exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001397 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001398}
Simon Butcher76a5b222018-04-22 22:57:27 +01001399#endif /* MBEDTLS_CIPHER_MODE_CFB */
1400
1401#if defined(MBEDTLS_CIPHER_MODE_OFB)
1402/*
1403 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1404 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001405int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1406 size_t length,
1407 size_t *iv_off,
1408 unsigned char iv[16],
1409 const unsigned char *input,
1410 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001411{
Simon Butcherad4e4932018-04-29 00:43:47 +01001412 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001413 size_t n;
1414
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001415 AES_VALIDATE_RET(ctx != NULL);
1416 AES_VALIDATE_RET(iv_off != NULL);
1417 AES_VALIDATE_RET(iv != NULL);
1418 AES_VALIDATE_RET(input != NULL);
1419 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001420
1421 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001422
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001423 if (n > 15) {
1424 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1425 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001426
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001427 while (length--) {
1428 if (n == 0) {
1429 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1430 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001431 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001432 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001433 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001434 *output++ = *input++ ^ iv[n];
1435
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001436 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001437 }
1438
1439 *iv_off = n;
1440
Simon Butcherad4e4932018-04-29 00:43:47 +01001441exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001442 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001443}
1444#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001446#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001447/*
1448 * AES-CTR buffer encryption/decryption
1449 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001450int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1451 size_t length,
1452 size_t *nc_off,
1453 unsigned char nonce_counter[16],
1454 unsigned char stream_block[16],
1455 const unsigned char *input,
1456 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001457{
Paul Bakker369e14b2012-04-18 14:16:09 +00001458 int c, i;
Gilles Peskine377a3102021-07-07 21:08:28 +02001459 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001460 size_t n;
1461
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001462 AES_VALIDATE_RET(ctx != NULL);
1463 AES_VALIDATE_RET(nc_off != NULL);
1464 AES_VALIDATE_RET(nonce_counter != NULL);
1465 AES_VALIDATE_RET(stream_block != NULL);
1466 AES_VALIDATE_RET(input != NULL);
1467 AES_VALIDATE_RET(output != NULL);
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001468
1469 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001470
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001471 if (n > 0x0F) {
1472 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1473 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001474
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001475 while (length--) {
1476 if (n == 0) {
1477 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1478 if (ret != 0) {
Gilles Peskine377a3102021-07-07 21:08:28 +02001479 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001480 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001481
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001482 for (i = 16; i > 0; i--) {
1483 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001484 break;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001485 }
1486 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001487 }
1488 c = *input++;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001489 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001490
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001491 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001492 }
1493
1494 *nc_off = n;
Gilles Peskine377a3102021-07-07 21:08:28 +02001495 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001496
Gilles Peskine377a3102021-07-07 21:08:28 +02001497exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001498 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001499}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001500#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001504#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001505/*
1506 * AES test vectors from:
1507 *
1508 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1509 */
1510static const unsigned char aes_test_ecb_dec[3][16] =
1511{
1512 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1513 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1514 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1515 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1516 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1517 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1518};
1519
1520static const unsigned char aes_test_ecb_enc[3][16] =
1521{
1522 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1523 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1524 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1525 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1526 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1527 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1528};
1529
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001531static const unsigned char aes_test_cbc_dec[3][16] =
1532{
1533 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1534 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1535 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1536 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1537 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1538 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1539};
1540
1541static const unsigned char aes_test_cbc_enc[3][16] =
1542{
1543 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1544 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1545 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1546 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1547 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1548 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1549};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001550#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001551
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001552#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001553/*
1554 * AES-CFB128 test vectors from:
1555 *
1556 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1557 */
1558static const unsigned char aes_test_cfb128_key[3][32] =
1559{
1560 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1561 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1562 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1563 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1564 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1565 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1566 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1567 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1568 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1569};
1570
1571static const unsigned char aes_test_cfb128_iv[16] =
1572{
1573 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1574 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1575};
1576
1577static const unsigned char aes_test_cfb128_pt[64] =
1578{
1579 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1580 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1581 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1582 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1583 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1584 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1585 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1586 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1587};
1588
1589static const unsigned char aes_test_cfb128_ct[3][64] =
1590{
1591 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1592 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1593 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1594 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1595 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1596 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1597 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1598 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1599 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1600 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1601 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1602 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1603 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1604 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1605 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1606 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1607 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1608 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1609 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1610 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1611 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1612 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1613 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1614 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1615};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001616#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001617
Simon Butcherad4e4932018-04-29 00:43:47 +01001618#if defined(MBEDTLS_CIPHER_MODE_OFB)
1619/*
1620 * AES-OFB test vectors from:
1621 *
Simon Butcher5db13622018-06-04 22:11:25 +01001622 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001623 */
1624static const unsigned char aes_test_ofb_key[3][32] =
1625{
1626 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1627 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1628 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1629 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1630 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1631 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1632 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1633 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1634 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1635};
1636
1637static const unsigned char aes_test_ofb_iv[16] =
1638{
1639 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1640 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1641};
1642
1643static const unsigned char aes_test_ofb_pt[64] =
1644{
1645 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1646 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1647 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1648 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1649 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1650 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1651 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1652 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1653};
1654
1655static const unsigned char aes_test_ofb_ct[3][64] =
1656{
1657 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1658 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1659 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1660 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1661 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1662 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1663 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1664 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1665 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1666 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1667 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1668 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1669 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1670 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1671 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1672 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1673 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1674 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1675 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1676 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1677 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1678 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1679 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1680 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1681};
1682#endif /* MBEDTLS_CIPHER_MODE_OFB */
1683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001684#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001685/*
1686 * AES-CTR test vectors from:
1687 *
1688 * http://www.faqs.org/rfcs/rfc3686.html
1689 */
1690
1691static const unsigned char aes_test_ctr_key[3][16] =
1692{
1693 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1694 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1695 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1696 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1697 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1698 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1699};
1700
1701static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1702{
1703 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1705 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1706 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1707 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1708 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1709};
1710
1711static const unsigned char aes_test_ctr_pt[3][48] =
1712{
1713 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1714 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1715
1716 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1717 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1718 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1719 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1720
1721 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1722 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1723 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1724 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1725 0x20, 0x21, 0x22, 0x23 }
1726};
1727
1728static const unsigned char aes_test_ctr_ct[3][48] =
1729{
1730 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1731 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1732 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1733 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1734 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1735 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1736 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1737 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1738 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1739 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1740 0x25, 0xB2, 0x07, 0x2F }
1741};
1742
1743static const int aes_test_ctr_len[3] =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001744{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001745#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001746
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001747#if defined(MBEDTLS_CIPHER_MODE_XTS)
1748/*
1749 * AES-XTS test vectors from:
1750 *
1751 * IEEE P1619/D16 Annex B
1752 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1753 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1754 */
1755static const unsigned char aes_test_xts_key[][32] =
1756{
1757 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1761 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1762 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1763 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1764 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1765 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1766 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1767 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1768 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1769};
1770
1771static const unsigned char aes_test_xts_pt32[][32] =
1772{
1773 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1777 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1778 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1779 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1780 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1781 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1782 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1783 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1784 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1785};
1786
1787static const unsigned char aes_test_xts_ct32[][32] =
1788{
1789 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1790 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1791 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1792 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1793 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1794 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1795 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1796 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1797 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1798 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1799 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1800 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1801};
1802
1803static const unsigned char aes_test_xts_data_unit[][16] =
1804{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001805 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1807 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1809 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001811};
1812
1813#endif /* MBEDTLS_CIPHER_MODE_XTS */
1814
Paul Bakker5121ce52009-01-03 21:22:43 +00001815/*
1816 * Checkup routine
1817 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001818int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001819{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001820 int ret = 0, i, j, u, mode;
1821 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001822 unsigned char key[32];
1823 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001824 const unsigned char *aes_tests;
Andrzej Kurek8ffd8a62022-09-27 07:54:16 -04001825#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1826 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001828#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001829#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001830 unsigned char prv[16];
1831#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001832#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1833 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001834 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001835#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001836#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001837 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001838#endif
1839#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001840 unsigned char nonce_counter[16];
1841 unsigned char stream_block[16];
1842#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001843 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001844
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001845 memset(key, 0, 32);
1846 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001847
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001848 if (verbose != 0) {
1849#if defined(MBEDTLS_AES_ALT)
1850 mbedtls_printf(" AES note: alternative implementation.\n");
1851#else /* MBEDTLS_AES_ALT */
1852#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1853 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1854 mbedtls_printf(" AES note: using VIA Padlock.\n");
1855 } else
1856#endif
1857#if defined(MBEDTLS_AESNI_HAVE_CODE)
1858 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Tom Cosgrove20458c02023-03-18 14:48:49 +00001859 mbedtls_printf(" AES note: using AESNI via ");
1860#if MBEDTLS_AESNI_HAVE_CODE == 1
1861 mbedtls_printf("assembly");
1862#elif MBEDTLS_AESNI_HAVE_CODE == 2
1863 mbedtls_printf("intrinsics");
1864#else
1865 mbedtls_printf("(unknown)");
1866#endif
1867 mbedtls_printf(".\n");
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001868 } else
1869#endif
Gilles Peskine2c8ad942023-03-10 22:35:24 +01001870 mbedtls_printf(" AES note: built-in implementation.\n");
1871#endif /* MBEDTLS_AES_ALT */
1872 }
1873
Paul Bakker5121ce52009-01-03 21:22:43 +00001874 /*
1875 * ECB mode
1876 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001877 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001879 keybits = 128 + u * 64;
1880 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001881
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001882 if (verbose != 0) {
1883 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1884 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001885 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001886
1887 memset(buf, 0, 16);
1888
1889 if (mode == MBEDTLS_AES_DECRYPT) {
1890 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1891 aes_tests = aes_test_ecb_dec[u];
1892 } else {
1893 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001894 aes_tests = aes_test_ecb_enc[u];
1895 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001897 /*
1898 * AES-192 is an optional feature that may be unavailable when
1899 * there is an alternative underlying implementation i.e. when
1900 * MBEDTLS_AES_ALT is defined.
1901 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001902 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1903 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001904 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001905 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001906 goto exit;
1907 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001908
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001909 for (j = 0; j < 10000; j++) {
1910 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1911 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001912 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001913 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001914 }
1915
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001916 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001917 ret = 1;
1918 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001919 }
1920
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001921 if (verbose != 0) {
1922 mbedtls_printf("passed\n");
1923 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001924 }
1925
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001926 if (verbose != 0) {
1927 mbedtls_printf("\n");
1928 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001929
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001930#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001931 /*
1932 * CBC mode
1933 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001934 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001935 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001936 keybits = 128 + u * 64;
1937 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001938
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001939 if (verbose != 0) {
1940 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1941 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001942 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001943
1944 memset(iv, 0, 16);
1945 memset(prv, 0, 16);
1946 memset(buf, 0, 16);
1947
1948 if (mode == MBEDTLS_AES_DECRYPT) {
1949 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1950 aes_tests = aes_test_cbc_dec[u];
1951 } else {
1952 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001953 aes_tests = aes_test_cbc_enc[u];
1954 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001955
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001956 /*
1957 * AES-192 is an optional feature that may be unavailable when
1958 * there is an alternative underlying implementation i.e. when
1959 * MBEDTLS_AES_ALT is defined.
1960 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001961 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1962 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001963 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001964 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001965 goto exit;
1966 }
1967
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001968 for (j = 0; j < 10000; j++) {
1969 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001970 unsigned char tmp[16];
1971
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001972 memcpy(tmp, prv, 16);
1973 memcpy(prv, buf, 16);
1974 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001975 }
1976
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001977 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1978 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001979 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001980 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001981
1982 }
1983
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001984 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001985 ret = 1;
1986 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001987 }
1988
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001989 if (verbose != 0) {
1990 mbedtls_printf("passed\n");
1991 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001992 }
1993
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001994 if (verbose != 0) {
1995 mbedtls_printf("\n");
1996 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001997#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001998
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001999#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002000 /*
2001 * CFB128 mode
2002 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002003 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00002004 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002005 keybits = 128 + u * 64;
2006 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002007
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002008 if (verbose != 0) {
2009 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2010 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2011 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002012
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002013 memcpy(iv, aes_test_cfb128_iv, 16);
2014 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002015
2016 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002017 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01002018 /*
2019 * AES-192 is an optional feature that may be unavailable when
2020 * there is an alternative underlying implementation i.e. when
2021 * MBEDTLS_AES_ALT is defined.
2022 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002023 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2024 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002025 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002026 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002027 goto exit;
2028 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002029
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002030 if (mode == MBEDTLS_AES_DECRYPT) {
2031 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002032 aes_tests = aes_test_cfb128_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002033 } else {
2034 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002035 aes_tests = aes_test_cfb128_ct[u];
2036 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002037
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002038 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2039 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002040 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002041 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002042
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002043 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002044 ret = 1;
2045 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00002046 }
2047
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002048 if (verbose != 0) {
2049 mbedtls_printf("passed\n");
2050 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002051 }
2052
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002053 if (verbose != 0) {
2054 mbedtls_printf("\n");
2055 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002056#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002057
Simon Butcherad4e4932018-04-29 00:43:47 +01002058#if defined(MBEDTLS_CIPHER_MODE_OFB)
2059 /*
2060 * OFB mode
2061 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002062 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002063 u = i >> 1;
2064 keybits = 128 + u * 64;
2065 mode = i & 1;
2066
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002067 if (verbose != 0) {
2068 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2069 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2070 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002071
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002072 memcpy(iv, aes_test_ofb_iv, 16);
2073 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002074
2075 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002076 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01002077 /*
2078 * AES-192 is an optional feature that may be unavailable when
2079 * there is an alternative underlying implementation i.e. when
2080 * MBEDTLS_AES_ALT is defined.
2081 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002082 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2083 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002084 continue;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002085 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002086 goto exit;
2087 }
2088
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002089 if (mode == MBEDTLS_AES_DECRYPT) {
2090 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002091 aes_tests = aes_test_ofb_pt;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002092 } else {
2093 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002094 aes_tests = aes_test_ofb_ct[u];
2095 }
2096
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002097 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2098 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002099 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002100 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002101
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002102 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002103 ret = 1;
2104 goto exit;
2105 }
2106
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002107 if (verbose != 0) {
2108 mbedtls_printf("passed\n");
2109 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002110 }
2111
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002112 if (verbose != 0) {
2113 mbedtls_printf("\n");
2114 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002115#endif /* MBEDTLS_CIPHER_MODE_OFB */
2116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002117#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002118 /*
2119 * CTR mode
2120 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002121 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002122 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002123 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002124
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002125 if (verbose != 0) {
2126 mbedtls_printf(" AES-CTR-128 (%s): ",
2127 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2128 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002129
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002130 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2131 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002132
2133 offset = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002134 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002135 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002136 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002137
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002138 len = aes_test_ctr_len[u];
2139
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002140 if (mode == MBEDTLS_AES_DECRYPT) {
2141 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002142 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002143 } else {
2144 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002145 aes_tests = aes_test_ctr_ct[u];
2146 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002147
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002148 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2149 stream_block, buf, buf);
2150 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002151 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002152 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002153
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002154 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002155 ret = 1;
2156 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002157 }
2158
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002159 if (verbose != 0) {
2160 mbedtls_printf("passed\n");
2161 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002162 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002163
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002164 if (verbose != 0) {
2165 mbedtls_printf("\n");
2166 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002167#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002168
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002169#if defined(MBEDTLS_CIPHER_MODE_XTS)
2170 {
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002171 static const int num_tests =
2172 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2173 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002174
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002175 /*
2176 * XTS mode
2177 */
2178 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002179
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002180 for (i = 0; i < num_tests << 1; i++) {
2181 const unsigned char *data_unit;
2182 u = i >> 1;
2183 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002184
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002185 if (verbose != 0) {
2186 mbedtls_printf(" AES-XTS-128 (%s): ",
2187 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2188 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002189
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002190 memset(key, 0, sizeof(key));
2191 memcpy(key, aes_test_xts_key[u], 32);
2192 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002193
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002194 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002195
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002196 if (mode == MBEDTLS_AES_DECRYPT) {
2197 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2198 if (ret != 0) {
2199 goto exit;
2200 }
2201 memcpy(buf, aes_test_xts_ct32[u], len);
2202 aes_tests = aes_test_xts_pt32[u];
2203 } else {
2204 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2205 if (ret != 0) {
2206 goto exit;
2207 }
2208 memcpy(buf, aes_test_xts_pt32[u], len);
2209 aes_tests = aes_test_xts_ct32[u];
2210 }
2211
2212
2213 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2214 buf, buf);
2215 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002216 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002217 }
2218
2219 if (memcmp(buf, aes_tests, len) != 0) {
2220 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002221 goto exit;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002222 }
2223
2224 if (verbose != 0) {
2225 mbedtls_printf("passed\n");
2226 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002227 }
2228
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002229 if (verbose != 0) {
2230 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002231 }
2232
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002233 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002234 }
2235#endif /* MBEDTLS_CIPHER_MODE_XTS */
2236
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002237 ret = 0;
2238
2239exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002240 if (ret != 0 && verbose != 0) {
2241 mbedtls_printf("failed\n");
2242 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002243
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002244 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002245
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01002246 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002247}
2248
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002249#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002251#endif /* MBEDTLS_AES_C */