blob: ced8a3263978b4f45ca321feb72487e878678553 [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{
Gilles Peskine7820a572021-07-07 21:08:28 +02001444 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001445
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001446 size_t offset = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001447
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001448 if (offset > 0x0F) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001449 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1450 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001451
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001452 for (size_t i = 0; i < length;) {
1453 size_t n = 16;
1454 if (offset == 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001455 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1456 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001457 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001458 }
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001459 for (int j = 16; j > 0; j--) {
1460 if (++nonce_counter[j - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001461 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 }
1463 }
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001464 } else {
1465 n -= offset;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001466 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001467
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001468 if (n > (length - i)) {
1469 n = (length - i);
1470 }
1471 mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
1472 // offset might be non-zero for the last block, but in that case, we don't use it again
1473 offset = 0;
1474 i += n;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001475 }
1476
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001477 // capture offset for future resumption
1478 *nc_off = (*nc_off + length) % 16;
1479
Gilles Peskine7820a572021-07-07 21:08:28 +02001480 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001481
Gilles Peskine7820a572021-07-07 21:08:28 +02001482exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001483 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001484}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001485#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001486
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001487#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001490/*
1491 * AES test vectors from:
1492 *
1493 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1494 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001495#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001496static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001497{
1498 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1499 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001500#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001501 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1502 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1503 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1504 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001505#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001506};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001507#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001508
Yanray Wang62c99912023-05-11 11:06:53 +08001509static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001510{
1511 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1512 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001513#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001514 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1515 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1516 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1517 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001518#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001519};
1520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001521#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001522static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001523{
1524 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1525 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001526#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001527 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1528 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1529 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1530 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001531#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001532};
1533
Yanray Wang62c99912023-05-11 11:06:53 +08001534static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001535{
1536 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1537 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001538#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001539 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1540 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1541 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1542 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001543#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001544};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001545#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001546
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001547#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001548/*
1549 * AES-CFB128 test vectors from:
1550 *
1551 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1552 */
Yanray Wang62c99912023-05-11 11:06:53 +08001553static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001554{
1555 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1556 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001557#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001558 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1559 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1560 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1561 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1562 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1563 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1564 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001565#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001566};
1567
1568static const unsigned char aes_test_cfb128_iv[16] =
1569{
1570 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1571 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1572};
1573
1574static const unsigned char aes_test_cfb128_pt[64] =
1575{
1576 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1577 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1578 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1579 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1580 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1581 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1582 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1583 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1584};
1585
Yanray Wang62c99912023-05-11 11:06:53 +08001586static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001587{
1588 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1589 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1590 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1591 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1592 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1593 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1594 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1595 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001596#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001597 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1598 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1599 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1600 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1601 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1602 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1603 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1604 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1605 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1606 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1607 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1608 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1609 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1610 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1611 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1612 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001613#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001614};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001615#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001616
Simon Butcherad4e4932018-04-29 00:43:47 +01001617#if defined(MBEDTLS_CIPHER_MODE_OFB)
1618/*
1619 * AES-OFB test vectors from:
1620 *
Simon Butcher5db13622018-06-04 22:11:25 +01001621 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001622 */
Yanray Wang62c99912023-05-11 11:06:53 +08001623static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001624{
1625 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1626 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001627#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001628 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1629 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1630 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1631 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1632 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1633 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1634 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001635#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001636};
1637
1638static const unsigned char aes_test_ofb_iv[16] =
1639{
1640 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1641 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1642};
1643
1644static const unsigned char aes_test_ofb_pt[64] =
1645{
1646 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1647 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1648 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1649 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1650 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1651 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1652 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1653 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1654};
1655
Yanray Wang62c99912023-05-11 11:06:53 +08001656static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001657{
1658 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1659 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1660 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1661 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1662 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1663 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1664 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1665 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001666#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001667 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1668 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1669 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1670 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1671 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1672 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1673 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1674 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1675 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1676 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1677 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1678 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1679 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1680 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1681 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1682 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001683#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001684};
1685#endif /* MBEDTLS_CIPHER_MODE_OFB */
1686
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001687#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001688/*
1689 * AES-CTR test vectors from:
1690 *
1691 * http://www.faqs.org/rfcs/rfc3686.html
1692 */
1693
Yanray Wang62c99912023-05-11 11:06:53 +08001694static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001695{
1696 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1697 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1698 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1699 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1700 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1701 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1702};
1703
Yanray Wang62c99912023-05-11 11:06:53 +08001704static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001705{
1706 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1708 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1709 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1710 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1711 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1712};
1713
Yanray Wang62c99912023-05-11 11:06:53 +08001714static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001715{
1716 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1717 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001718 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1719 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1720 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1721 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1722
1723 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1724 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1725 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1726 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1727 0x20, 0x21, 0x22, 0x23 }
1728};
1729
Yanray Wang62c99912023-05-11 11:06:53 +08001730static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001731{
1732 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1733 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1734 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1735 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1736 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1737 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1738 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1739 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1740 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1741 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1742 0x25, 0xB2, 0x07, 0x2F }
1743};
1744
1745static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001746{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001747#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001748
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001749#if defined(MBEDTLS_CIPHER_MODE_XTS)
1750/*
1751 * AES-XTS test vectors from:
1752 *
1753 * IEEE P1619/D16 Annex B
1754 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1755 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1756 */
1757static const unsigned char aes_test_xts_key[][32] =
1758{
1759 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1761 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1762 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1763 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1764 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1765 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1766 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1767 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1768 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1769 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1770 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1771};
1772
1773static const unsigned char aes_test_xts_pt32[][32] =
1774{
1775 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1779 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1780 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1781 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1782 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1783 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1784 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1785 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1786 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1787};
1788
1789static const unsigned char aes_test_xts_ct32[][32] =
1790{
1791 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1792 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1793 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1794 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1795 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1796 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1797 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1798 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1799 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1800 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1801 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1802 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1803};
1804
1805static const unsigned char aes_test_xts_data_unit[][16] =
1806{
Gilles Peskine449bd832023-01-11 14:50:10 +01001807 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1809 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1811 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001813};
1814
1815#endif /* MBEDTLS_CIPHER_MODE_XTS */
1816
Paul Bakker5121ce52009-01-03 21:22:43 +00001817/*
1818 * Checkup routine
1819 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001820int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001821{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001822 int ret = 0, i, j, u, mode;
1823 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001824 unsigned char key[32];
1825 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001826 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001827#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1828 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001829 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001830#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001831#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001832 unsigned char prv[16];
1833#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001834#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1835 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001836 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001837#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001838#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001839 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001840#endif
1841#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001842 unsigned char nonce_counter[16];
1843 unsigned char stream_block[16];
1844#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001845 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
Gilles Peskine449bd832023-01-11 14:50:10 +01001847 memset(key, 0, 32);
1848 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001849
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001850 if (verbose != 0) {
1851#if defined(MBEDTLS_AES_ALT)
1852 mbedtls_printf(" AES note: alternative implementation.\n");
1853#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001854#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001855#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001856 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001857#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001858 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001859#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001860#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001861#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001862 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1863 mbedtls_printf(" AES note: using AESNI.\n");
1864 } else
1865#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001866#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001867 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1868 mbedtls_printf(" AES note: using VIA Padlock.\n");
1869 } else
1870#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001871#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001872 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001873 mbedtls_printf(" AES note: using AESCE.\n");
1874 } else
1875#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001876 {
1877#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1878 mbedtls_printf(" AES note: built-in implementation.\n");
1879#endif
1880 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001881#endif /* MBEDTLS_AES_ALT */
1882 }
1883
Paul Bakker5121ce52009-01-03 21:22:43 +00001884 /*
1885 * ECB mode
1886 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001887 {
1888 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001889 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001890
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001891 for (i = 0; i < num_tests << 1; i++) {
1892 u = i >> 1;
1893 keybits = 128 + u * 64;
1894 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001895
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001896 if (verbose != 0) {
1897 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1898 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1899 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001900#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001901 if (mode == MBEDTLS_AES_DECRYPT) {
1902 if (verbose != 0) {
1903 mbedtls_printf("skipped\n");
1904 }
1905 continue;
1906 }
1907#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001908
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001909 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001910
Yanray Wangb67b4742023-10-31 17:10:32 +08001911#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001912 if (mode == MBEDTLS_AES_DECRYPT) {
1913 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1914 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001915 } else
1916#endif
1917 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001918 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1919 aes_tests = aes_test_ecb_enc[u];
1920 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001921
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001922 /*
1923 * AES-192 is an optional feature that may be unavailable when
1924 * there is an alternative underlying implementation i.e. when
1925 * MBEDTLS_AES_ALT is defined.
1926 */
1927 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1928 mbedtls_printf("skipped\n");
1929 continue;
1930 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001931 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001932 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001933
1934 for (j = 0; j < 10000; j++) {
1935 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1936 if (ret != 0) {
1937 goto exit;
1938 }
1939 }
1940
1941 if (memcmp(buf, aes_tests, 16) != 0) {
1942 ret = 1;
1943 goto exit;
1944 }
1945
1946 if (verbose != 0) {
1947 mbedtls_printf("passed\n");
1948 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001949 }
1950
Gilles Peskine449bd832023-01-11 14:50:10 +01001951 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001952 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001953 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001954 }
1955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001956#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001957 /*
1958 * CBC mode
1959 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001960 {
1961 static const int num_tests =
1962 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001963
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001964 for (i = 0; i < num_tests << 1; i++) {
1965 u = i >> 1;
1966 keybits = 128 + u * 64;
1967 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001968
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001969 if (verbose != 0) {
1970 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1971 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001972 }
1973
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001974 memset(iv, 0, 16);
1975 memset(prv, 0, 16);
1976 memset(buf, 0, 16);
1977
1978 if (mode == MBEDTLS_AES_DECRYPT) {
1979 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1980 aes_tests = aes_test_cbc_dec[u];
1981 } else {
1982 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1983 aes_tests = aes_test_cbc_enc[u];
1984 }
1985
1986 /*
1987 * AES-192 is an optional feature that may be unavailable when
1988 * there is an alternative underlying implementation i.e. when
1989 * MBEDTLS_AES_ALT is defined.
1990 */
1991 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1992 mbedtls_printf("skipped\n");
1993 continue;
1994 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001995 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001996 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001997
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001998 for (j = 0; j < 10000; j++) {
1999 if (mode == MBEDTLS_AES_ENCRYPT) {
2000 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002001
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002002 memcpy(tmp, prv, 16);
2003 memcpy(prv, buf, 16);
2004 memcpy(buf, tmp, 16);
2005 }
2006
2007 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2008 if (ret != 0) {
2009 goto exit;
2010 }
2011
2012 }
2013
2014 if (memcmp(buf, aes_tests, 16) != 0) {
2015 ret = 1;
2016 goto exit;
2017 }
2018
2019 if (verbose != 0) {
2020 mbedtls_printf("passed\n");
2021 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002022 }
2023
Gilles Peskine449bd832023-01-11 14:50:10 +01002024 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002025 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002026 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002027 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002028#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002030#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002031 /*
2032 * CFB128 mode
2033 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002034 {
2035 static const int num_tests =
2036 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002037
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002038 for (i = 0; i < num_tests << 1; i++) {
2039 u = i >> 1;
2040 keybits = 128 + u * 64;
2041 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002042
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002043 if (verbose != 0) {
2044 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2045 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2046 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002047
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002048 memcpy(iv, aes_test_cfb128_iv, 16);
2049 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002050
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002051 offset = 0;
2052 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2053 /*
2054 * AES-192 is an optional feature that may be unavailable when
2055 * there is an alternative underlying implementation i.e. when
2056 * MBEDTLS_AES_ALT is defined.
2057 */
2058 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2059 mbedtls_printf("skipped\n");
2060 continue;
2061 } else if (ret != 0) {
2062 goto exit;
2063 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002064
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002065 if (mode == MBEDTLS_AES_DECRYPT) {
2066 memcpy(buf, aes_test_cfb128_ct[u], 64);
2067 aes_tests = aes_test_cfb128_pt;
2068 } else {
2069 memcpy(buf, aes_test_cfb128_pt, 64);
2070 aes_tests = aes_test_cfb128_ct[u];
2071 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002072
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002073 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2074 if (ret != 0) {
2075 goto exit;
2076 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002077
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002078 if (memcmp(buf, aes_tests, 64) != 0) {
2079 ret = 1;
2080 goto exit;
2081 }
2082
2083 if (verbose != 0) {
2084 mbedtls_printf("passed\n");
2085 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002086 }
2087
Gilles Peskine449bd832023-01-11 14:50:10 +01002088 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002089 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002090 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002091 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002092#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002093
Simon Butcherad4e4932018-04-29 00:43:47 +01002094#if defined(MBEDTLS_CIPHER_MODE_OFB)
2095 /*
2096 * OFB mode
2097 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002098 {
2099 static const int num_tests =
2100 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002101
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002102 for (i = 0; i < num_tests << 1; i++) {
2103 u = i >> 1;
2104 keybits = 128 + u * 64;
2105 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002106
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002107 if (verbose != 0) {
2108 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2109 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2110 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002111
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002112 memcpy(iv, aes_test_ofb_iv, 16);
2113 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002114
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002115 offset = 0;
2116 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2117 /*
2118 * AES-192 is an optional feature that may be unavailable when
2119 * there is an alternative underlying implementation i.e. when
2120 * MBEDTLS_AES_ALT is defined.
2121 */
2122 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2123 mbedtls_printf("skipped\n");
2124 continue;
2125 } else if (ret != 0) {
2126 goto exit;
2127 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002128
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002129 if (mode == MBEDTLS_AES_DECRYPT) {
2130 memcpy(buf, aes_test_ofb_ct[u], 64);
2131 aes_tests = aes_test_ofb_pt;
2132 } else {
2133 memcpy(buf, aes_test_ofb_pt, 64);
2134 aes_tests = aes_test_ofb_ct[u];
2135 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002136
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002137 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2138 if (ret != 0) {
2139 goto exit;
2140 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002141
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002142 if (memcmp(buf, aes_tests, 64) != 0) {
2143 ret = 1;
2144 goto exit;
2145 }
2146
2147 if (verbose != 0) {
2148 mbedtls_printf("passed\n");
2149 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002150 }
2151
Gilles Peskine449bd832023-01-11 14:50:10 +01002152 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002153 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002154 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002155 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002156#endif /* MBEDTLS_CIPHER_MODE_OFB */
2157
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002158#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002159 /*
2160 * CTR mode
2161 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002162 {
2163 static const int num_tests =
2164 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002165
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002166 for (i = 0; i < num_tests << 1; i++) {
2167 u = i >> 1;
2168 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002169
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002170 if (verbose != 0) {
2171 mbedtls_printf(" AES-CTR-128 (%s): ",
2172 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2173 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002174
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002175 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2176 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002177
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002178 offset = 0;
2179 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2180 goto exit;
2181 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002182
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002183 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002184
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002185 if (mode == MBEDTLS_AES_DECRYPT) {
2186 memcpy(buf, aes_test_ctr_ct[u], len);
2187 aes_tests = aes_test_ctr_pt[u];
2188 } else {
2189 memcpy(buf, aes_test_ctr_pt[u], len);
2190 aes_tests = aes_test_ctr_ct[u];
2191 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002192
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002193 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2194 stream_block, buf, buf);
2195 if (ret != 0) {
2196 goto exit;
2197 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002198
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002199 if (memcmp(buf, aes_tests, len) != 0) {
2200 ret = 1;
2201 goto exit;
2202 }
2203
2204 if (verbose != 0) {
2205 mbedtls_printf("passed\n");
2206 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002207 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002208 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002209
Gilles Peskine449bd832023-01-11 14:50:10 +01002210 if (verbose != 0) {
2211 mbedtls_printf("\n");
2212 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002213#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002214
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002215#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002216 /*
2217 * XTS mode
2218 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002219 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002220 static const int num_tests =
2221 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2222 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002223
Gilles Peskine449bd832023-01-11 14:50:10 +01002224 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002225
Gilles Peskine449bd832023-01-11 14:50:10 +01002226 for (i = 0; i < num_tests << 1; i++) {
2227 const unsigned char *data_unit;
2228 u = i >> 1;
2229 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002230
Gilles Peskine449bd832023-01-11 14:50:10 +01002231 if (verbose != 0) {
2232 mbedtls_printf(" AES-XTS-128 (%s): ",
2233 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2234 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002235
Gilles Peskine449bd832023-01-11 14:50:10 +01002236 memset(key, 0, sizeof(key));
2237 memcpy(key, aes_test_xts_key[u], 32);
2238 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002239
Gilles Peskine449bd832023-01-11 14:50:10 +01002240 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002241
Gilles Peskine449bd832023-01-11 14:50:10 +01002242 if (mode == MBEDTLS_AES_DECRYPT) {
2243 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2244 if (ret != 0) {
2245 goto exit;
2246 }
2247 memcpy(buf, aes_test_xts_ct32[u], len);
2248 aes_tests = aes_test_xts_pt32[u];
2249 } else {
2250 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2251 if (ret != 0) {
2252 goto exit;
2253 }
2254 memcpy(buf, aes_test_xts_pt32[u], len);
2255 aes_tests = aes_test_xts_ct32[u];
2256 }
2257
2258
2259 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2260 buf, buf);
2261 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002262 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002263 }
2264
2265 if (memcmp(buf, aes_tests, len) != 0) {
2266 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002267 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002268 }
2269
2270 if (verbose != 0) {
2271 mbedtls_printf("passed\n");
2272 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002273 }
2274
Gilles Peskine449bd832023-01-11 14:50:10 +01002275 if (verbose != 0) {
2276 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002277 }
2278
Gilles Peskine449bd832023-01-11 14:50:10 +01002279 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002280 }
2281#endif /* MBEDTLS_CIPHER_MODE_XTS */
2282
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002283 ret = 0;
2284
2285exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002286 if (ret != 0 && verbose != 0) {
2287 mbedtls_printf("failed\n");
2288 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002289
Gilles Peskine449bd832023-01-11 14:50:10 +01002290 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002291
Gilles Peskine449bd832023-01-11 14:50:10 +01002292 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002293}
2294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002295#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002296
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002297#endif /* MBEDTLS_AES_C */