blob: f4b9739f7f434820a79fa2dc4969130acfb312d5 [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
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
9 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010010 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
12 */
13
Gilles Peskinedb09ef62020-06-03 01:43:33 +020014#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000017
Rich Evans00ab4702015-02-06 13:43:58 +000018#include <string.h>
19
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000020#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030021#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050022#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000023#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080024
Dave Rodgman782df0352023-09-29 12:57:52 +010025#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Dave Rodgman9fd1b522023-10-10 15:23:44 +010026#if !((defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_AESCE_C)) || \
27 (defined(MBEDTLS_ARCH_IS_X64) && defined(MBEDTLS_AESNI_C)) || \
28 (defined(MBEDTLS_ARCH_IS_X86) && defined(MBEDTLS_AESNI_C)))
Jerry Yu69436812023-04-25 11:08:30 +080029#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080030#endif
31#endif
32
Dave Rodgmane81a6322023-09-29 13:54:27 +010033#if defined(MBEDTLS_ARCH_IS_X86)
Jerry Yu61fc5ed2023-08-18 17:28:48 +080034#if defined(MBEDTLS_PADLOCK_C)
35#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080036#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
37#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080038#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
39#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
40 "MBEDTLS_PADLOCK_C is set"
41#endif
42#endif
Jerry Yu02b15192023-04-23 14:43:19 +080043#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000046#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000047#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000049#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010050#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080051#if defined(MBEDTLS_AESCE_C)
52#include "aesce.h"
53#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000054
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010056
Yanray Wangf03b4912023-11-09 11:23:17 +080057/*
58 * This is a convenience shorthand macro to check if we need reverse S-box and
59 * reverse tables. It's private and only defined in this file.
60 */
61#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \
62 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \
Yanray Wangb67b4742023-10-31 17:10:32 +080063 !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wangdbcc0c62023-08-30 15:04:01 +080064#define MBEDTLS_AES_NEED_REVERSE_TABLES
65#endif
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020068
Jerry Yu9e628622023-08-17 11:20:09 +080069#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000070static int aes_padlock_ace = -1;
71#endif
72
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000074/*
75 * Forward S-box
76 */
Dave Rodgman18ddf612023-10-04 14:03:12 +010077MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +000078{
79 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
80 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
81 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
82 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
83 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
84 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
85 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
86 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
87 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
88 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
89 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
90 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
91 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
92 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
93 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
94 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
95 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
96 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
97 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
98 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
99 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
100 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
101 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
102 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
103 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
104 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
105 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
106 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
107 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
108 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
109 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
110 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
111};
112
113/*
114 * Forward tables
115 */
116#define FT \
117\
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
119 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
120 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
121 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
122 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
123 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
124 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
125 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
126 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
127 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
128 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
129 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
130 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
131 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
132 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
133 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
134 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
135 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
136 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
137 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
138 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
139 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
140 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
141 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
142 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
143 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
144 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
145 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
146 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
147 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
148 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
149 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
150 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
151 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
152 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
153 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
154 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
155 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
156 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
157 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
158 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
159 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
160 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
161 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
162 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
163 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
164 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
165 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
166 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
167 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
168 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
169 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
170 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
171 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
172 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
173 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
174 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
175 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
176 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
177 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
178 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
179 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
180 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
181 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 +0000182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100184MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000185#undef V
186
Gilles Peskine449bd832023-01-11 14:50:10 +0100187#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100188MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000189#undef V
190
Gilles Peskine449bd832023-01-11 14:50:10 +0100191#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100192MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000193#undef V
194
Gilles Peskine449bd832023-01-11 14:50:10 +0100195#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100196MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000197#undef V
198
199#undef FT
200
201/*
202 * Reverse S-box
203 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100204MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000205{
206 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
207 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
208 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
209 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
210 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
211 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
212 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
213 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
214 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
215 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
216 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
217 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
218 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
219 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
220 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
221 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
222 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
223 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
224 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
225 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
226 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
227 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
228 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
229 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
230 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
231 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
232 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
233 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
234 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
235 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
236 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
237 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
238};
239
240/*
241 * Reverse tables
242 */
243#define RT \
244\
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
246 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
247 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
248 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
249 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
250 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
251 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
252 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
253 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
254 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
255 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
256 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
257 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
258 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
259 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
260 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
261 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
262 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
263 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
264 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
265 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
266 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
267 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
268 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
269 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
270 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
271 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
272 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
273 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
274 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
275 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
276 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
277 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
278 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
279 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
280 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
281 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
282 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
283 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
284 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
285 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
286 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
287 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
288 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
289 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
290 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
291 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
292 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
293 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
294 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
295 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
296 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
297 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
298 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
299 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
300 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
301 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
302 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
303 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
304 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
305 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
306 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
307 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
308 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 +0000309
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100312MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000313#undef V
314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100316MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000317#undef V
318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100320MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000321#undef V
322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100324MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000325#undef V
326
327#undef RT
328
329/*
330 * Round constants
331 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100332MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000333{
334 0x00000001, 0x00000002, 0x00000004, 0x00000008,
335 0x00000010, 0x00000020, 0x00000040, 0x00000080,
336 0x0000001B, 0x00000036
337};
338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341/*
342 * Forward S-box & tables
343 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100344MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
345MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
346MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
347MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
348MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000349
350/*
351 * Reverse S-box & tables
352 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100353MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100354
Dave Rodgman18ddf612023-10-04 14:03:12 +0100355MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
356MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
357MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
358MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360/*
361 * Round constants
362 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100363MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
365/*
366 * Tables generation code
367 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100368#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
369#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
370#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
Dave Rodgman18ddf612023-10-04 14:03:12 +0100372MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
Dave Rodgman18ddf612023-10-04 14:03:12 +0100374MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000375{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800376 int i;
377 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800378 uint8_t pow[256];
379 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000380
381 /*
382 * compute pow and log tables over GF(2^8)
383 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000385 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800386 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800387 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000388 }
389
390 /*
391 * calculate the round constants
392 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200394 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800395 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 }
397
398 /*
399 * generate the forward and reverse S-boxes
400 */
401 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800402#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800404#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000407 x = pow[255 - log[i]];
408
Yanray Wangfe944ce2023-06-26 18:16:01 +0800409 y = x; y = (y << 1) | (y >> 7);
410 x ^= y; y = (y << 1) | (y >> 7);
411 x ^= y; y = (y << 1) | (y >> 7);
412 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 x ^= y ^ 0x63;
414
Yanray Wangfe944ce2023-06-26 18:16:01 +0800415 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800416#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000417 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800418#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 }
420
421 /*
422 * generate the forward and reverse tables
423 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800426 y = XTIME(x);
427 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
Gilles Peskine449bd832023-01-11 14:50:10 +0100429 FT0[i] = ((uint32_t) y) ^
430 ((uint32_t) x << 8) ^
431 ((uint32_t) x << 16) ^
432 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000433
Hanno Beckerad049a92017-06-19 16:31:54 +0100434#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 FT1[i] = ROTL8(FT0[i]);
436 FT2[i] = ROTL8(FT1[i]);
437 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100438#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800440#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 x = RSb[i];
442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
444 ((uint32_t) MUL(0x09, x) << 8) ^
445 ((uint32_t) MUL(0x0D, x) << 16) ^
446 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Hanno Beckerad049a92017-06-19 16:31:54 +0100448#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 RT1[i] = ROTL8(RT0[i]);
450 RT2[i] = ROTL8(RT1[i]);
451 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100452#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800453#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000454 }
455}
456
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200457#undef ROTL8
458
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
Hanno Beckerad049a92017-06-19 16:31:54 +0100461#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200462
Gilles Peskine449bd832023-01-11 14:50:10 +0100463#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
464#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
465#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200466
467#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100468#define AES_RT1(idx) ROTL8(RT0[idx])
469#define AES_RT2(idx) ROTL16(RT0[idx])
470#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200471
472#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100473#define AES_FT1(idx) ROTL8(FT0[idx])
474#define AES_FT2(idx) ROTL16(FT0[idx])
475#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200476
Hanno Becker177d3cf2017-06-07 15:52:48 +0100477#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200478
479#define AES_RT0(idx) RT0[idx]
480#define AES_RT1(idx) RT1[idx]
481#define AES_RT2(idx) RT2[idx]
482#define AES_RT3(idx) RT3[idx]
483
484#define AES_FT0(idx) FT0[idx]
485#define AES_FT1(idx) FT1[idx]
486#define AES_FT2(idx) FT2[idx]
487#define AES_FT3(idx) FT3[idx]
488
Hanno Becker177d3cf2017-06-07 15:52:48 +0100489#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200490
Gilles Peskine449bd832023-01-11 14:50:10 +0100491void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200492{
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200494}
495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200497{
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200499 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200503}
504
Jaeden Amero9366feb2018-05-29 18:55:17 +0100505#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100506void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100507{
Gilles Peskine449bd832023-01-11 14:50:10 +0100508 mbedtls_aes_init(&ctx->crypt);
509 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100510}
511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100513{
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100515 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 }
Simon Butcher5201e412018-12-06 17:40:14 +0000517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 mbedtls_aes_free(&ctx->crypt);
519 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100520}
521#endif /* MBEDTLS_CIPHER_MODE_XTS */
522
Gilles Peskine0de8f852023-03-16 17:14:59 +0100523/* Some implementations need the round keys to be aligned.
524 * Return an offset to be added to buf, such that (buf + offset) is
525 * correctly aligned.
526 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
527 * i.e. an offset of 1 means 4 bytes and so on.
528 */
Jerry Yu96084472023-08-17 18:10:45 +0800529#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100530 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100531#define MAY_NEED_TO_ALIGN
532#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100533
Dave Rodgman18ddf612023-10-04 14:03:12 +0100534MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100535{
536#if defined(MAY_NEED_TO_ALIGN)
537 int align_16_bytes = 0;
538
Jerry Yu9e628622023-08-17 11:20:09 +0800539#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100540 if (aes_padlock_ace == -1) {
541 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
542 }
543 if (aes_padlock_ace) {
544 align_16_bytes = 1;
545 }
546#endif
547
Gilles Peskine9c682e72023-03-16 17:21:33 +0100548#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100549 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
550 align_16_bytes = 1;
551 }
552#endif
553
554 if (align_16_bytes) {
555 /* These implementations needs 16-byte alignment
556 * for the round key array. */
557 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
558 if (delta == 0) {
559 return 0;
560 } else {
561 return 4 - delta; // 16 bytes = 4 uint32_t
562 }
563 }
564#else /* MAY_NEED_TO_ALIGN */
565 (void) buf;
566#endif /* MAY_NEED_TO_ALIGN */
567
568 return 0;
569}
570
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 Peskine449bd832023-01-11 14:50:10 +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 Bakker5c2364c2012-10-01 14:41:15 +0000578 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000581 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800582#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000583 case 192: ctx->nr = 12; break;
584 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800585#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 }
588
Simon Butcher5201e412018-12-06 17:40:14 +0000589#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100590 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000591 aes_gen_tables();
592 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000593 }
594#endif
595
Gilles Peskine0de8f852023-03-16 17:14:59 +0100596 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100597 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100599#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
601 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
602 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100603#endif
604
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800605#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100606 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800607 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
608 }
609#endif
610
Jerry Yu29c91ba2023-08-04 11:02:04 +0800611#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800612 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000614 }
615
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000617 case 10:
618
Jerry Yu3a0f0442023-08-17 17:06:21 +0800619 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200620 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
622 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
623 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
624 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
626 RK[5] = RK[1] ^ RK[4];
627 RK[6] = RK[2] ^ RK[5];
628 RK[7] = RK[3] ^ RK[6];
629 }
630 break;
631
Arto Kinnunen732ca322023-04-14 14:26:10 +0800632#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 case 12:
634
Jerry Yu3a0f0442023-08-17 17:06:21 +0800635 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200636 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
638 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
639 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
640 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
642 RK[7] = RK[1] ^ RK[6];
643 RK[8] = RK[2] ^ RK[7];
644 RK[9] = RK[3] ^ RK[8];
645 RK[10] = RK[4] ^ RK[9];
646 RK[11] = RK[5] ^ RK[10];
647 }
648 break;
649
650 case 14:
651
Jerry Yu3a0f0442023-08-17 17:06:21 +0800652 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200653 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
655 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
656 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
657 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000658
659 RK[9] = RK[1] ^ RK[8];
660 RK[10] = RK[2] ^ RK[9];
661 RK[11] = RK[3] ^ RK[10];
662
663 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
665 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
666 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
667 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
669 RK[13] = RK[5] ^ RK[12];
670 RK[14] = RK[6] ^ RK[13];
671 RK[15] = RK[7] ^ RK[14];
672 }
673 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800674#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000675 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000676
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800678#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000679}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200680#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000681
682/*
683 * AES key schedule (decryption)
684 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800685#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100686int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
687 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000688{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800689#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800690 uint32_t *SK;
691#endif
692 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000694 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800695
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000698
Gilles Peskine0de8f852023-03-16 17:14:59 +0100699 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100700 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000701
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200702 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200704 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000706
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200707 ctx->nr = cty.nr;
708
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100709#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
711 mbedtls_aesni_inverse_key((unsigned char *) RK,
712 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200713 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100714 }
715#endif
716
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800717#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100718 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800719 mbedtls_aesce_inverse_key(
720 (unsigned char *) RK,
721 (const unsigned char *) (cty.buf + cty.rk_offset),
722 ctx->nr);
723 goto exit;
724 }
725#endif
726
Jerry Yu29c91ba2023-08-04 11:02:04 +0800727#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100728 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000729
730 *RK++ = *SK++;
731 *RK++ = *SK++;
732 *RK++ = *SK++;
733 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800734 SK -= 8;
735 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
736 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100737 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
738 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
739 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
740 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 }
742 }
743
744 *RK++ = *SK++;
745 *RK++ = *SK++;
746 *RK++ = *SK++;
747 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800748#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200749exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000751
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000753}
Yanray Wangb67b4742023-10-31 17:10:32 +0800754#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100755
756#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100757static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
758 unsigned int keybits,
759 const unsigned char **key1,
760 unsigned int *key1bits,
761 const unsigned char **key2,
762 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100763{
764 const unsigned int half_keybits = keybits / 2;
765 const unsigned int half_keybytes = half_keybits / 8;
766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100768 case 256: break;
769 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100770 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100771 }
772
773 *key1bits = half_keybits;
774 *key2bits = half_keybits;
775 *key1 = &key[0];
776 *key2 = &key[half_keybytes];
777
778 return 0;
779}
780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
782 const unsigned char *key,
783 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100784{
Janos Follath24eed8d2019-11-22 13:21:35 +0000785 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100786 const unsigned char *key1, *key2;
787 unsigned int key1bits, key2bits;
788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
790 &key2, &key2bits);
791 if (ret != 0) {
792 return ret;
793 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100794
795 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
797 if (ret != 0) {
798 return ret;
799 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100800
801 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100802 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100803}
804
Gilles Peskine449bd832023-01-11 14:50:10 +0100805int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
806 const unsigned char *key,
807 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808{
Janos Follath24eed8d2019-11-22 13:21:35 +0000809 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100810 const unsigned char *key1, *key2;
811 unsigned int key1bits, key2bits;
812
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
814 &key2, &key2bits);
815 if (ret != 0) {
816 return ret;
817 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818
819 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
821 if (ret != 0) {
822 return ret;
823 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100824
825 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100827}
828#endif /* MBEDTLS_CIPHER_MODE_XTS */
829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100831 do \
832 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
834 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
835 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
836 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100837 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
839 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
840 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
841 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100842 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
844 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
845 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
846 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100847 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
849 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
850 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
851 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
852 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000853
Gilles Peskine449bd832023-01-11 14:50:10 +0100854#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100855 do \
856 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
858 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
859 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
860 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100861 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
863 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
864 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
865 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100866 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
868 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
869 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
870 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100871 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
873 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
874 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
875 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
876 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000877
878/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200879 * AES-ECB block encryption
880 */
881#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100882int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
883 const unsigned char input[16],
884 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200885{
886 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100887 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100888 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200889 uint32_t X[4];
890 uint32_t Y[4];
891 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200892
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
894 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
895 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
896 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
899 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]);
900 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 +0200901 }
902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 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 +0200904
Gilles Peskine5197c662020-08-26 17:03:24 +0200905 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
907 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
908 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
909 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200910
Gilles Peskine5197c662020-08-26 17:03:24 +0200911 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
913 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
914 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
915 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200916
Gilles Peskine5197c662020-08-26 17:03:24 +0200917 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
919 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
920 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
921 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200922
Gilles Peskine5197c662020-08-26 17:03:24 +0200923 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100924 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
925 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
926 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
927 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200928
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
930 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
931 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
932 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500935
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200937}
938#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
939
940/*
941 * AES-ECB block decryption
942 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800943#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100944int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
945 const unsigned char input[16],
946 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947{
948 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100949 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200951 uint32_t X[4];
952 uint32_t Y[4];
953 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
956 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
957 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
958 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
961 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]);
962 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 +0200963 }
964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 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 +0200966
Gilles Peskine5197c662020-08-26 17:03:24 +0200967 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
969 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
970 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
971 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200972
Gilles Peskine5197c662020-08-26 17:03:24 +0200973 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100974 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
975 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
976 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200978
Gilles Peskine5197c662020-08-26 17:03:24 +0200979 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
981 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
982 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200984
Gilles Peskine5197c662020-08-26 17:03:24 +0200985 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100986 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
987 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
988 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
992 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
993 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
994 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000995
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500997
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200999}
Yanray Wangb67b4742023-10-31 17:10:32 +08001000#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001001
Gilles Peskine148cad12023-03-16 13:08:42 +01001002/* VIA Padlock and our intrinsics-based implementation of AESNI require
1003 * the round keys to be aligned on a 16-byte boundary. We take care of this
1004 * before creating them, but the AES context may have moved (this can happen
1005 * if the library is called from a language with managed memory), and in later
1006 * calls it might have a different alignment with respect to 16-byte memory.
1007 * So we may need to realign.
1008 */
Dave Rodgman18ddf612023-10-04 14:03:12 +01001009MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +01001010{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001011 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1012 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001013 memmove(ctx->buf + new_offset, // new address
1014 ctx->buf + ctx->rk_offset, // current address
1015 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1016 ctx->rk_offset = new_offset;
1017 }
1018}
Gilles Peskine148cad12023-03-16 13:08:42 +01001019
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001020/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001021 * AES-ECB block encryption/decryption
1022 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001023int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1024 int mode,
1025 const unsigned char input[16],
1026 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001027{
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001029 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001031
Gilles Peskine0de8f852023-03-16 17:14:59 +01001032#if defined(MAY_NEED_TO_ALIGN)
1033 aes_maybe_realign(ctx);
1034#endif
1035
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001036#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001037 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1038 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1039 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001040#endif
1041
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001042#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001043 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001044 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1045 }
1046#endif
1047
Jerry Yu9e628622023-08-17 11:20:09 +08001048#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001050 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001051 }
1052#endif
1053
Jerry Yu29c91ba2023-08-04 11:02:04 +08001054#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001055#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang111159b2023-11-10 13:41:12 +08001056 if (mode == MBEDTLS_AES_DECRYPT) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang111159b2023-11-10 13:41:12 +08001058 } else
Jerry Yu29c91ba2023-08-04 11:02:04 +08001059#endif
Yanray Wang111159b2023-11-10 13:41:12 +08001060 {
1061 return mbedtls_internal_aes_encrypt(ctx, input, output);
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001062 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001063#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
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)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001067
Paul Bakker5121ce52009-01-03 21:22:43 +00001068/*
1069 * AES-CBC buffer encryption/decryption
1070 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001071int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1072 int mode,
1073 size_t length,
1074 unsigned char iv[16],
1075 const unsigned char *input,
1076 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001077{
Gilles Peskine7820a572021-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 Peskine449bd832023-01-11 14:50:10 +01001081 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001082 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001084
Paul Elliott2ad93672023-08-11 11:07:06 +01001085 /* Nothing to do if length is zero. */
1086 if (length == 0) {
1087 return 0;
1088 }
1089
Gilles Peskine449bd832023-01-11 14:50:10 +01001090 if (length % 16) {
1091 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1092 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001093
Jerry Yu9e628622023-08-17 11:20:09 +08001094#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 if (aes_padlock_ace > 0) {
1096 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1097 return 0;
1098 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001099
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001100 // If padlock data misaligned, we just fall back to
1101 // unaccelerated mode
1102 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001103 }
1104#endif
1105
Dave Rodgman906c63c2023-06-14 17:53:51 +01001106 const unsigned char *ivp = iv;
1107
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 if (mode == MBEDTLS_AES_DECRYPT) {
1109 while (length > 0) {
1110 memcpy(temp, input, 16);
1111 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1112 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001113 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001115 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001116 * the result for the next block in CBC, and the cost of transferring that data from
1117 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001118 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001121
1122 input += 16;
1123 output += 16;
1124 length -= 16;
1125 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 } else {
1127 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001128 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1131 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001132 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001134 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
1136 input += 16;
1137 output += 16;
1138 length -= 16;
1139 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001140 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001141 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001142 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001143
Gilles Peskine7820a572021-07-07 21:08:28 +02001144exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001146}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001147#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001148
Aorimn5f778012016-06-09 23:22:58 +02001149#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001150
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001151typedef unsigned char mbedtls_be128[16];
1152
1153/*
1154 * GF(2^128) multiplication function
1155 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001156 * This function multiplies a field element by x in the polynomial field
1157 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001158 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001159 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001160 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001161#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001162MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001163#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001164static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001165 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001166{
1167 uint64_t a, b, ra, rb;
1168
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 a = MBEDTLS_GET_UINT64_LE(x, 0);
1170 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001171
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1173 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001174
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1176 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001177}
1178
Aorimn5f778012016-06-09 23:22:58 +02001179/*
1180 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001181 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001182 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001183 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001184 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001185#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001186MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001187#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001188int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1189 int mode,
1190 size_t length,
1191 const unsigned char data_unit[16],
1192 const unsigned char *input,
1193 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001194{
Janos Follath24eed8d2019-11-22 13:21:35 +00001195 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001196 size_t blocks = length / 16;
1197 size_t leftover = length % 16;
1198 unsigned char tweak[16];
1199 unsigned char prev_tweak[16];
1200 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001201
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001203 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001204 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001205
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001206 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001207 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001208 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 }
Aorimn5f778012016-06-09 23:22:58 +02001210
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001211 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001213 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 }
Aorimn5f778012016-06-09 23:22:58 +02001215
Jaeden Amerod82cd862018-04-28 15:02:45 +01001216 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1218 data_unit, tweak);
1219 if (ret != 0) {
1220 return ret;
1221 }
Aorimn5f778012016-06-09 23:22:58 +02001222
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001224 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001225 /* We are on the last block in a decrypt operation that has
1226 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001227 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001228 * the leftovers and then update the current tweak for use on this,
1229 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001230 memcpy(prev_tweak, tweak, sizeof(tweak));
1231 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001232 }
1233
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001235
Gilles Peskine449bd832023-01-11 14:50:10 +01001236 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1237 if (ret != 0) {
1238 return ret;
1239 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001240
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001242
1243 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001245
1246 output += 16;
1247 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001248 }
1249
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001251 /* If we are on the leftover bytes in a decrypt operation, we need to
1252 * use the previous tweak for these bytes (as saved in prev_tweak). */
1253 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001254
Jaeden Amerod82cd862018-04-28 15:02:45 +01001255 /* We are now on the final part of the data unit, which doesn't divide
1256 * evenly by 16. It's time for ciphertext stealing. */
1257 size_t i;
1258 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001259
Jaeden Amerod82cd862018-04-28 15:02:45 +01001260 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001261 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001263 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001264 }
Aorimn5f778012016-06-09 23:22:58 +02001265
Dave Rodgman069e7f42022-11-24 19:37:26 +00001266 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001268
Jaeden Amerod82cd862018-04-28 15:02:45 +01001269 /* Copy ciphertext bytes from the previous block for input in this
1270 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001272
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1274 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001276 }
Aorimn5f778012016-06-09 23:22:58 +02001277
Jaeden Amerod82cd862018-04-28 15:02:45 +01001278 /* Write the result back to the previous block, overriding the previous
1279 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001281 }
1282
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001284}
1285#endif /* MBEDTLS_CIPHER_MODE_XTS */
1286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001287#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001288/*
1289 * AES-CFB128 buffer encryption/decryption
1290 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001291int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1292 int mode,
1293 size_t length,
1294 size_t *iv_off,
1295 unsigned char iv[16],
1296 const unsigned char *input,
1297 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001298{
Paul Bakker27fdf462011-06-09 13:55:13 +00001299 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001300 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001301 size_t n;
1302
Gilles Peskine449bd832023-01-11 14:50:10 +01001303 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001304 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001305 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001306
1307 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001308
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 if (n > 15) {
1310 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1311 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001312
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 if (mode == MBEDTLS_AES_DECRYPT) {
1314 while (length--) {
1315 if (n == 0) {
1316 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1317 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001318 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001319 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001320 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001321
1322 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001324 iv[n] = (unsigned char) c;
1325
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001327 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 } else {
1329 while (length--) {
1330 if (n == 0) {
1331 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1332 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001333 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001335 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001336
Gilles Peskine449bd832023-01-11 14:50:10 +01001337 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001338
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001340 }
1341 }
1342
1343 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001344 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001345
Gilles Peskine7820a572021-07-07 21:08:28 +02001346exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001348}
Paul Bakker556efba2014-01-24 15:38:12 +01001349
1350/*
1351 * AES-CFB8 buffer encryption/decryption
1352 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001353int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1354 int mode,
1355 size_t length,
1356 unsigned char iv[16],
1357 const unsigned char *input,
1358 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001359{
Gilles Peskine7820a572021-07-07 21:08:28 +02001360 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001361 unsigned char c;
1362 unsigned char ov[17];
1363
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001365 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001366 }
1367 while (length--) {
1368 memcpy(ov, iv, 16);
1369 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1370 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001371 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 }
Paul Bakker556efba2014-01-24 15:38:12 +01001373
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001375 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 }
Paul Bakker556efba2014-01-24 15:38:12 +01001377
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001379
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001381 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 }
Paul Bakker556efba2014-01-24 15:38:12 +01001383
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001385 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001386 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001387
Gilles Peskine7820a572021-07-07 21:08:28 +02001388exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001390}
Simon Butcher76a5b222018-04-22 22:57:27 +01001391#endif /* MBEDTLS_CIPHER_MODE_CFB */
1392
1393#if defined(MBEDTLS_CIPHER_MODE_OFB)
1394/*
1395 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1396 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001397int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1398 size_t length,
1399 size_t *iv_off,
1400 unsigned char iv[16],
1401 const unsigned char *input,
1402 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001403{
Simon Butcherad4e4932018-04-29 00:43:47 +01001404 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001405 size_t n;
1406
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001407 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001408
Gilles Peskine449bd832023-01-11 14:50:10 +01001409 if (n > 15) {
1410 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1411 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001412
Gilles Peskine449bd832023-01-11 14:50:10 +01001413 while (length--) {
1414 if (n == 0) {
1415 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1416 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001417 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001419 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001420 *output++ = *input++ ^ iv[n];
1421
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001423 }
1424
1425 *iv_off = n;
1426
Simon Butcherad4e4932018-04-29 00:43:47 +01001427exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001428 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001429}
1430#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001432#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001433/*
1434 * AES-CTR buffer encryption/decryption
1435 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001436int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1437 size_t length,
1438 size_t *nc_off,
1439 unsigned char nonce_counter[16],
1440 unsigned char stream_block[16],
1441 const unsigned char *input,
1442 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001443{
Paul Bakker369e14b2012-04-18 14:16:09 +00001444 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001445 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001446 size_t n;
1447
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001448 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001449
Gilles Peskine449bd832023-01-11 14:50:10 +01001450 if (n > 0x0F) {
1451 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1452 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001453
Gilles Peskine449bd832023-01-11 14:50:10 +01001454 while (length--) {
1455 if (n == 0) {
1456 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1457 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001458 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001460
Gilles Peskine449bd832023-01-11 14:50:10 +01001461 for (i = 16; i > 0; i--) {
1462 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001463 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001464 }
1465 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001466 }
1467 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001468 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001469
Gilles Peskine449bd832023-01-11 14:50:10 +01001470 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001471 }
1472
1473 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001474 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001475
Gilles Peskine7820a572021-07-07 21:08:28 +02001476exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001477 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001478}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001479#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001481#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001483#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001484/*
1485 * AES test vectors from:
1486 *
1487 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1488 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001489#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001490static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001491{
1492 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1493 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001494#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001495 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1496 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1497 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1498 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001499#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001500};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001501#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001502
Yanray Wang62c99912023-05-11 11:06:53 +08001503static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001504{
1505 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1506 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001507#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001508 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1509 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1510 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1511 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001512#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001513};
1514
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001515#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001516static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001517{
1518 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1519 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001520#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001521 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1522 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1523 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1524 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001525#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001526};
1527
Yanray Wang62c99912023-05-11 11:06:53 +08001528static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001529{
1530 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1531 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001532#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001533 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1534 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1535 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1536 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001537#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001538};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001539#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001540
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001541#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001542/*
1543 * AES-CFB128 test vectors from:
1544 *
1545 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1546 */
Yanray Wang62c99912023-05-11 11:06:53 +08001547static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001548{
1549 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1550 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001551#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001552 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1553 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1554 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1555 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1556 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1557 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1558 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001559#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001560};
1561
1562static const unsigned char aes_test_cfb128_iv[16] =
1563{
1564 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1565 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1566};
1567
1568static const unsigned char aes_test_cfb128_pt[64] =
1569{
1570 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1571 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1572 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1573 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1574 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1575 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1576 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1577 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1578};
1579
Yanray Wang62c99912023-05-11 11:06:53 +08001580static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001581{
1582 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1583 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1584 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1585 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1586 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1587 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1588 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1589 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001590#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001591 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1592 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1593 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1594 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1595 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1596 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1597 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1598 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1599 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1600 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1601 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1602 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1603 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1604 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1605 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1606 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001607#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001608};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001609#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001610
Simon Butcherad4e4932018-04-29 00:43:47 +01001611#if defined(MBEDTLS_CIPHER_MODE_OFB)
1612/*
1613 * AES-OFB test vectors from:
1614 *
Simon Butcher5db13622018-06-04 22:11:25 +01001615 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001616 */
Yanray Wang62c99912023-05-11 11:06:53 +08001617static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001618{
1619 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1620 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001621#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001622 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1623 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1624 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1625 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1626 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1627 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1628 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001629#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001630};
1631
1632static const unsigned char aes_test_ofb_iv[16] =
1633{
1634 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1635 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1636};
1637
1638static const unsigned char aes_test_ofb_pt[64] =
1639{
1640 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1641 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1642 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1643 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1644 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1645 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1646 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1647 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1648};
1649
Yanray Wang62c99912023-05-11 11:06:53 +08001650static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001651{
1652 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1653 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1654 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1655 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1656 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1657 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1658 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1659 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001660#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001661 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1662 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1663 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1664 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1665 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1666 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1667 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1668 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1669 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1670 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1671 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1672 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1673 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1674 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1675 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1676 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001677#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001678};
1679#endif /* MBEDTLS_CIPHER_MODE_OFB */
1680
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001681#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001682/*
1683 * AES-CTR test vectors from:
1684 *
1685 * http://www.faqs.org/rfcs/rfc3686.html
1686 */
1687
Yanray Wang62c99912023-05-11 11:06:53 +08001688static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001689{
1690 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1691 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1692 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1693 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1694 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1695 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1696};
1697
Yanray Wang62c99912023-05-11 11:06:53 +08001698static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001699{
1700 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1702 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1703 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1704 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1705 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1706};
1707
Yanray Wang62c99912023-05-11 11:06:53 +08001708static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001709{
1710 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1711 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001712 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1713 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1714 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1715 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1716
1717 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1718 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1719 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1720 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1721 0x20, 0x21, 0x22, 0x23 }
1722};
1723
Yanray Wang62c99912023-05-11 11:06:53 +08001724static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001725{
1726 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1727 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1728 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1729 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1730 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1731 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1732 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1733 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1734 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1735 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1736 0x25, 0xB2, 0x07, 0x2F }
1737};
1738
1739static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001740{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001741#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001742
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001743#if defined(MBEDTLS_CIPHER_MODE_XTS)
1744/*
1745 * AES-XTS test vectors from:
1746 *
1747 * IEEE P1619/D16 Annex B
1748 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1749 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1750 */
1751static const unsigned char aes_test_xts_key[][32] =
1752{
1753 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1757 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1758 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1759 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1760 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1761 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1762 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1763 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1764 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1765};
1766
1767static const unsigned char aes_test_xts_pt32[][32] =
1768{
1769 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1772 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1773 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1774 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1775 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1776 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1777 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1778 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1779 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1780 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1781};
1782
1783static const unsigned char aes_test_xts_ct32[][32] =
1784{
1785 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1786 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1787 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1788 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1789 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1790 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1791 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1792 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1793 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1794 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1795 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1796 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1797};
1798
1799static const unsigned char aes_test_xts_data_unit[][16] =
1800{
Gilles Peskine449bd832023-01-11 14:50:10 +01001801 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1803 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1805 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001807};
1808
1809#endif /* MBEDTLS_CIPHER_MODE_XTS */
1810
Paul Bakker5121ce52009-01-03 21:22:43 +00001811/*
1812 * Checkup routine
1813 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001814int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001815{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001816 int ret = 0, i, j, u, mode;
1817 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001818 unsigned char key[32];
1819 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001820 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001821#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1822 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001824#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001826 unsigned char prv[16];
1827#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001828#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1829 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001830 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001831#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001832#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001833 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001834#endif
1835#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001836 unsigned char nonce_counter[16];
1837 unsigned char stream_block[16];
1838#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001839 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
Gilles Peskine449bd832023-01-11 14:50:10 +01001841 memset(key, 0, 32);
1842 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001843
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001844 if (verbose != 0) {
1845#if defined(MBEDTLS_AES_ALT)
1846 mbedtls_printf(" AES note: alternative implementation.\n");
1847#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001848#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001849#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001850 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001851#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001852 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001853#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001854#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001855#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001856 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1857 mbedtls_printf(" AES note: using AESNI.\n");
1858 } else
1859#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001860#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001861 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1862 mbedtls_printf(" AES note: using VIA Padlock.\n");
1863 } else
1864#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001865#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001866 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001867 mbedtls_printf(" AES note: using AESCE.\n");
1868 } else
1869#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001870 {
1871#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1872 mbedtls_printf(" AES note: built-in implementation.\n");
1873#endif
1874 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001875#endif /* MBEDTLS_AES_ALT */
1876 }
1877
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 /*
1879 * ECB mode
1880 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001881 {
1882 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001883 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001884
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001885 for (i = 0; i < num_tests << 1; i++) {
1886 u = i >> 1;
1887 keybits = 128 + u * 64;
1888 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001889
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001890 if (verbose != 0) {
1891 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1892 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1893 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001894#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001895 if (mode == MBEDTLS_AES_DECRYPT) {
1896 if (verbose != 0) {
1897 mbedtls_printf("skipped\n");
1898 }
1899 continue;
1900 }
1901#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001902
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001903 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001904
Yanray Wangb67b4742023-10-31 17:10:32 +08001905#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001906 if (mode == MBEDTLS_AES_DECRYPT) {
1907 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1908 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001909 } else
1910#endif
1911 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001912 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1913 aes_tests = aes_test_ecb_enc[u];
1914 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001915
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001916 /*
1917 * AES-192 is an optional feature that may be unavailable when
1918 * there is an alternative underlying implementation i.e. when
1919 * MBEDTLS_AES_ALT is defined.
1920 */
1921 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1922 mbedtls_printf("skipped\n");
1923 continue;
1924 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001925 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001926 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001927
1928 for (j = 0; j < 10000; j++) {
1929 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1930 if (ret != 0) {
1931 goto exit;
1932 }
1933 }
1934
1935 if (memcmp(buf, aes_tests, 16) != 0) {
1936 ret = 1;
1937 goto exit;
1938 }
1939
1940 if (verbose != 0) {
1941 mbedtls_printf("passed\n");
1942 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001943 }
1944
Gilles Peskine449bd832023-01-11 14:50:10 +01001945 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001946 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001947 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001948 }
1949
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001950#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001951 /*
1952 * CBC mode
1953 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001954 {
1955 static const int num_tests =
1956 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001957
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001958 for (i = 0; i < num_tests << 1; i++) {
1959 u = i >> 1;
1960 keybits = 128 + u * 64;
1961 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001962
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001963 if (verbose != 0) {
1964 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1965 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001966 }
1967
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001968 memset(iv, 0, 16);
1969 memset(prv, 0, 16);
1970 memset(buf, 0, 16);
1971
1972 if (mode == MBEDTLS_AES_DECRYPT) {
1973 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1974 aes_tests = aes_test_cbc_dec[u];
1975 } else {
1976 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1977 aes_tests = aes_test_cbc_enc[u];
1978 }
1979
1980 /*
1981 * AES-192 is an optional feature that may be unavailable when
1982 * there is an alternative underlying implementation i.e. when
1983 * MBEDTLS_AES_ALT is defined.
1984 */
1985 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1986 mbedtls_printf("skipped\n");
1987 continue;
1988 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001989 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001990 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001991
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001992 for (j = 0; j < 10000; j++) {
1993 if (mode == MBEDTLS_AES_ENCRYPT) {
1994 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001995
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001996 memcpy(tmp, prv, 16);
1997 memcpy(prv, buf, 16);
1998 memcpy(buf, tmp, 16);
1999 }
2000
2001 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2002 if (ret != 0) {
2003 goto exit;
2004 }
2005
2006 }
2007
2008 if (memcmp(buf, aes_tests, 16) != 0) {
2009 ret = 1;
2010 goto exit;
2011 }
2012
2013 if (verbose != 0) {
2014 mbedtls_printf("passed\n");
2015 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002016 }
2017
Gilles Peskine449bd832023-01-11 14:50:10 +01002018 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002019 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002020 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002021 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002022#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002023
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002024#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002025 /*
2026 * CFB128 mode
2027 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002028 {
2029 static const int num_tests =
2030 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002031
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002032 for (i = 0; i < num_tests << 1; i++) {
2033 u = i >> 1;
2034 keybits = 128 + u * 64;
2035 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002036
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002037 if (verbose != 0) {
2038 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2039 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2040 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002041
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002042 memcpy(iv, aes_test_cfb128_iv, 16);
2043 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002044
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002045 offset = 0;
2046 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2047 /*
2048 * AES-192 is an optional feature that may be unavailable when
2049 * there is an alternative underlying implementation i.e. when
2050 * MBEDTLS_AES_ALT is defined.
2051 */
2052 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2053 mbedtls_printf("skipped\n");
2054 continue;
2055 } else if (ret != 0) {
2056 goto exit;
2057 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002058
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002059 if (mode == MBEDTLS_AES_DECRYPT) {
2060 memcpy(buf, aes_test_cfb128_ct[u], 64);
2061 aes_tests = aes_test_cfb128_pt;
2062 } else {
2063 memcpy(buf, aes_test_cfb128_pt, 64);
2064 aes_tests = aes_test_cfb128_ct[u];
2065 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002066
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002067 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2068 if (ret != 0) {
2069 goto exit;
2070 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002071
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002072 if (memcmp(buf, aes_tests, 64) != 0) {
2073 ret = 1;
2074 goto exit;
2075 }
2076
2077 if (verbose != 0) {
2078 mbedtls_printf("passed\n");
2079 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002080 }
2081
Gilles Peskine449bd832023-01-11 14:50:10 +01002082 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002083 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002084 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002085 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002086#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002087
Simon Butcherad4e4932018-04-29 00:43:47 +01002088#if defined(MBEDTLS_CIPHER_MODE_OFB)
2089 /*
2090 * OFB mode
2091 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002092 {
2093 static const int num_tests =
2094 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002095
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 for (i = 0; i < num_tests << 1; i++) {
2097 u = i >> 1;
2098 keybits = 128 + u * 64;
2099 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002100
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002101 if (verbose != 0) {
2102 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2103 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2104 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002105
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002106 memcpy(iv, aes_test_ofb_iv, 16);
2107 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002108
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002109 offset = 0;
2110 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2111 /*
2112 * AES-192 is an optional feature that may be unavailable when
2113 * there is an alternative underlying implementation i.e. when
2114 * MBEDTLS_AES_ALT is defined.
2115 */
2116 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2117 mbedtls_printf("skipped\n");
2118 continue;
2119 } else if (ret != 0) {
2120 goto exit;
2121 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002122
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002123 if (mode == MBEDTLS_AES_DECRYPT) {
2124 memcpy(buf, aes_test_ofb_ct[u], 64);
2125 aes_tests = aes_test_ofb_pt;
2126 } else {
2127 memcpy(buf, aes_test_ofb_pt, 64);
2128 aes_tests = aes_test_ofb_ct[u];
2129 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002130
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002131 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2132 if (ret != 0) {
2133 goto exit;
2134 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002135
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002136 if (memcmp(buf, aes_tests, 64) != 0) {
2137 ret = 1;
2138 goto exit;
2139 }
2140
2141 if (verbose != 0) {
2142 mbedtls_printf("passed\n");
2143 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002144 }
2145
Gilles Peskine449bd832023-01-11 14:50:10 +01002146 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002147 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002148 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002149 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002150#endif /* MBEDTLS_CIPHER_MODE_OFB */
2151
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002152#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002153 /*
2154 * CTR mode
2155 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002156 {
2157 static const int num_tests =
2158 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002159
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002160 for (i = 0; i < num_tests << 1; i++) {
2161 u = i >> 1;
2162 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002163
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002164 if (verbose != 0) {
2165 mbedtls_printf(" AES-CTR-128 (%s): ",
2166 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2167 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002168
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002169 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2170 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002171
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002172 offset = 0;
2173 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2174 goto exit;
2175 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002176
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002177 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002178
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002179 if (mode == MBEDTLS_AES_DECRYPT) {
2180 memcpy(buf, aes_test_ctr_ct[u], len);
2181 aes_tests = aes_test_ctr_pt[u];
2182 } else {
2183 memcpy(buf, aes_test_ctr_pt[u], len);
2184 aes_tests = aes_test_ctr_ct[u];
2185 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002186
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002187 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2188 stream_block, buf, buf);
2189 if (ret != 0) {
2190 goto exit;
2191 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002192
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002193 if (memcmp(buf, aes_tests, len) != 0) {
2194 ret = 1;
2195 goto exit;
2196 }
2197
2198 if (verbose != 0) {
2199 mbedtls_printf("passed\n");
2200 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002201 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002202 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002203
Gilles Peskine449bd832023-01-11 14:50:10 +01002204 if (verbose != 0) {
2205 mbedtls_printf("\n");
2206 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002207#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002208
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002209#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002210 /*
2211 * XTS mode
2212 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002213 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002214 static const int num_tests =
2215 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2216 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002217
Gilles Peskine449bd832023-01-11 14:50:10 +01002218 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002219
Gilles Peskine449bd832023-01-11 14:50:10 +01002220 for (i = 0; i < num_tests << 1; i++) {
2221 const unsigned char *data_unit;
2222 u = i >> 1;
2223 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002224
Gilles Peskine449bd832023-01-11 14:50:10 +01002225 if (verbose != 0) {
2226 mbedtls_printf(" AES-XTS-128 (%s): ",
2227 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2228 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002229
Gilles Peskine449bd832023-01-11 14:50:10 +01002230 memset(key, 0, sizeof(key));
2231 memcpy(key, aes_test_xts_key[u], 32);
2232 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002233
Gilles Peskine449bd832023-01-11 14:50:10 +01002234 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002235
Gilles Peskine449bd832023-01-11 14:50:10 +01002236 if (mode == MBEDTLS_AES_DECRYPT) {
2237 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2238 if (ret != 0) {
2239 goto exit;
2240 }
2241 memcpy(buf, aes_test_xts_ct32[u], len);
2242 aes_tests = aes_test_xts_pt32[u];
2243 } else {
2244 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2245 if (ret != 0) {
2246 goto exit;
2247 }
2248 memcpy(buf, aes_test_xts_pt32[u], len);
2249 aes_tests = aes_test_xts_ct32[u];
2250 }
2251
2252
2253 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2254 buf, buf);
2255 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002256 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002257 }
2258
2259 if (memcmp(buf, aes_tests, len) != 0) {
2260 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002261 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002262 }
2263
2264 if (verbose != 0) {
2265 mbedtls_printf("passed\n");
2266 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002267 }
2268
Gilles Peskine449bd832023-01-11 14:50:10 +01002269 if (verbose != 0) {
2270 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002271 }
2272
Gilles Peskine449bd832023-01-11 14:50:10 +01002273 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002274 }
2275#endif /* MBEDTLS_CIPHER_MODE_XTS */
2276
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002277 ret = 0;
2278
2279exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002280 if (ret != 0 && verbose != 0) {
2281 mbedtls_printf("failed\n");
2282 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002283
Gilles Peskine449bd832023-01-11 14:50:10 +01002284 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002285
Gilles Peskine449bd832023-01-11 14:50:10 +01002286 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002287}
2288
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002289#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002290
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002291#endif /* MBEDTLS_AES_C */