blob: 203db0dcd7aebe1ad317c50a4b028312fce0bbaf [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000034#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010035#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080036#if defined(MBEDTLS_AESCE_C)
37#include "aesce.h"
38#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/platform.h"
Dave Rodgman591ff052024-01-13 16:42:38 +000041#include "ctr.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010042
Yanray Wangf03b4912023-11-09 11:23:17 +080043/*
44 * This is a convenience shorthand macro to check if we need reverse S-box and
45 * reverse tables. It's private and only defined in this file.
46 */
47#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \
48 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \
Yanray Wangb67b4742023-10-31 17:10:32 +080049 !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wangdbcc0c62023-08-30 15:04:01 +080050#define MBEDTLS_AES_NEED_REVERSE_TABLES
51#endif
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020054
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000056/*
57 * Forward S-box
58 */
Dave Rodgman18ddf612023-10-04 14:03:12 +010059MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +000060{
61 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
62 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
63 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
64 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
65 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
66 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
67 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
68 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
69 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
70 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
71 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
72 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
73 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
74 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
75 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
76 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
77 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
78 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
79 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
80 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
81 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
82 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
83 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
84 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
85 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
86 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
87 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
88 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
89 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
90 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
91 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
92 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
93};
94
95/*
96 * Forward tables
97 */
98#define FT \
99\
Gilles Peskine449bd832023-01-11 14:50:10 +0100100 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
101 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
102 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
103 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
104 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
105 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
106 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
107 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
108 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
109 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
110 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
111 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
112 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
113 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
114 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
115 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
116 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
117 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
118 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
119 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
120 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
121 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
122 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
123 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
124 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
125 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
126 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
127 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
128 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
129 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
130 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
131 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
132 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
133 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
134 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
135 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
136 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
137 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
138 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
139 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
140 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
141 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
142 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
143 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
144 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
145 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
146 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
147 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
148 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
149 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
150 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
151 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
152 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
153 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
154 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
155 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
156 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
157 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
158 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
159 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
160 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
161 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
162 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
163 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 +0000164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100166MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000167#undef V
168
Gilles Peskine449bd832023-01-11 14:50:10 +0100169#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100170MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000171#undef V
172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100174MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000175#undef V
176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100178MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000179#undef V
180
181#undef FT
182
183/*
184 * Reverse S-box
185 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100186MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000187{
188 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
189 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
190 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
191 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
192 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
193 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
194 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
195 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
196 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
197 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
198 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
199 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
200 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
201 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
202 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
203 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
204 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
205 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
206 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
207 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
208 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
209 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
210 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
211 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
212 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
213 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
214 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
215 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
216 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
217 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
218 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
219 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
220};
221
222/*
223 * Reverse tables
224 */
225#define RT \
226\
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
228 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
229 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
230 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
231 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
232 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
233 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
234 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
235 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
236 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
237 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
238 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
239 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
240 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
241 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
242 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
243 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
244 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
245 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
246 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
247 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
248 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
249 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
250 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
251 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
252 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
253 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
254 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
255 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
256 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
257 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
258 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
259 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
260 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
261 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
262 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
263 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
264 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
265 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
266 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
267 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
268 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
269 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
270 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
271 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
272 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
273 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
274 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
275 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
276 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
277 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
278 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
279 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
280 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
281 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
282 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
283 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
284 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
285 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
286 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
287 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
288 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
289 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
290 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 +0000291
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100294MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000295#undef V
296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100298MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000299#undef V
300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100302MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000303#undef V
304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100306MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000307#undef V
308
309#undef RT
310
311/*
312 * Round constants
313 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100314MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000315{
316 0x00000001, 0x00000002, 0x00000004, 0x00000008,
317 0x00000010, 0x00000020, 0x00000040, 0x00000080,
318 0x0000001B, 0x00000036
319};
320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000322
323/*
324 * Forward S-box & tables
325 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100326MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
327MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
328MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
329MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
330MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000331
332/*
333 * Reverse S-box & tables
334 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100335MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100336
Dave Rodgman18ddf612023-10-04 14:03:12 +0100337MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
338MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
339MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
340MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342/*
343 * Round constants
344 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100345MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347/*
348 * Tables generation code
349 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100350#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
351#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
352#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
Dave Rodgman18ddf612023-10-04 14:03:12 +0100354MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000355
Dave Rodgman18ddf612023-10-04 14:03:12 +0100356MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000357{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800358 int i;
359 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800360 uint8_t pow[256];
361 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
363 /*
364 * compute pow and log tables over GF(2^8)
365 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000367 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800368 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800369 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000370 }
371
372 /*
373 * calculate the round constants
374 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200376 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800377 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 }
379
380 /*
381 * generate the forward and reverse S-boxes
382 */
383 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800384#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000385 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800386#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000389 x = pow[255 - log[i]];
390
Yanray Wangfe944ce2023-06-26 18:16:01 +0800391 y = x; y = (y << 1) | (y >> 7);
392 x ^= y; y = (y << 1) | (y >> 7);
393 x ^= y; y = (y << 1) | (y >> 7);
394 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 x ^= y ^ 0x63;
396
Yanray Wangfe944ce2023-06-26 18:16:01 +0800397 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800398#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800400#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 }
402
403 /*
404 * generate the forward and reverse tables
405 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100406 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000407 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800408 y = XTIME(x);
409 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 FT0[i] = ((uint32_t) y) ^
412 ((uint32_t) x << 8) ^
413 ((uint32_t) x << 16) ^
414 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Hanno Beckerad049a92017-06-19 16:31:54 +0100416#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 FT1[i] = ROTL8(FT0[i]);
418 FT2[i] = ROTL8(FT1[i]);
419 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100420#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800422#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 x = RSb[i];
424
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
426 ((uint32_t) MUL(0x09, x) << 8) ^
427 ((uint32_t) MUL(0x0D, x) << 16) ^
428 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Hanno Beckerad049a92017-06-19 16:31:54 +0100430#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 RT1[i] = ROTL8(RT0[i]);
432 RT2[i] = ROTL8(RT1[i]);
433 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100434#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800435#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 }
437}
438
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200439#undef ROTL8
440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Hanno Beckerad049a92017-06-19 16:31:54 +0100443#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
446#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
447#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200448
449#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100450#define AES_RT1(idx) ROTL8(RT0[idx])
451#define AES_RT2(idx) ROTL16(RT0[idx])
452#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200453
454#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100455#define AES_FT1(idx) ROTL8(FT0[idx])
456#define AES_FT2(idx) ROTL16(FT0[idx])
457#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200458
Hanno Becker177d3cf2017-06-07 15:52:48 +0100459#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200460
461#define AES_RT0(idx) RT0[idx]
462#define AES_RT1(idx) RT1[idx]
463#define AES_RT2(idx) RT2[idx]
464#define AES_RT3(idx) RT3[idx]
465
466#define AES_FT0(idx) FT0[idx]
467#define AES_FT1(idx) FT1[idx]
468#define AES_FT2(idx) FT2[idx]
469#define AES_FT3(idx) FT3[idx]
470
Hanno Becker177d3cf2017-06-07 15:52:48 +0100471#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200474{
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200476}
477
Gilles Peskine449bd832023-01-11 14:50:10 +0100478void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200479{
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200481 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200483
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200485}
486
Jaeden Amero9366feb2018-05-29 18:55:17 +0100487#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100488void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100489{
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_aes_init(&ctx->crypt);
491 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100492}
493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100495{
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100497 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 }
Simon Butcher5201e412018-12-06 17:40:14 +0000499
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 mbedtls_aes_free(&ctx->crypt);
501 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100502}
503#endif /* MBEDTLS_CIPHER_MODE_XTS */
504
Gilles Peskine0de8f852023-03-16 17:14:59 +0100505/* Some implementations need the round keys to be aligned.
506 * Return an offset to be added to buf, such that (buf + offset) is
507 * correctly aligned.
508 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
509 * i.e. an offset of 1 means 4 bytes and so on.
510 */
Thomas Daubney62af02c2024-06-14 10:37:13 +0100511#if (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100512#define MAY_NEED_TO_ALIGN
513#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100514
Dave Rodgman18ddf612023-10-04 14:03:12 +0100515MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100516{
517#if defined(MAY_NEED_TO_ALIGN)
518 int align_16_bytes = 0;
519
Gilles Peskine9c682e72023-03-16 17:21:33 +0100520#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100521 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
522 align_16_bytes = 1;
523 }
524#endif
525
526 if (align_16_bytes) {
527 /* These implementations needs 16-byte alignment
528 * for the round key array. */
529 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
530 if (delta == 0) {
531 return 0;
532 } else {
533 return 4 - delta; // 16 bytes = 4 uint32_t
534 }
535 }
536#else /* MAY_NEED_TO_ALIGN */
537 (void) buf;
538#endif /* MAY_NEED_TO_ALIGN */
539
540 return 0;
541}
542
Paul Bakker5121ce52009-01-03 21:22:43 +0000543/*
544 * AES key schedule (encryption)
545 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200546#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100547int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
548 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000549{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000550 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000551
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000553 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800554#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000555 case 192: ctx->nr = 12; break;
556 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800557#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000559 }
560
Simon Butcher5201e412018-12-06 17:40:14 +0000561#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000563 aes_gen_tables();
564 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000565 }
566#endif
567
Gilles Peskine0de8f852023-03-16 17:14:59 +0100568 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100569 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100571#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100572 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
573 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
574 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100575#endif
576
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800577#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100578 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800579 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
580 }
581#endif
582
Jerry Yu29c91ba2023-08-04 11:02:04 +0800583#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800584 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000586 }
587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000589 case 10:
590
Jerry Yu3a0f0442023-08-17 17:06:21 +0800591 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200592 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100593 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
594 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
595 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
596 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000597
598 RK[5] = RK[1] ^ RK[4];
599 RK[6] = RK[2] ^ RK[5];
600 RK[7] = RK[3] ^ RK[6];
601 }
602 break;
603
Arto Kinnunen732ca322023-04-14 14:26:10 +0800604#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000605 case 12:
606
Jerry Yu3a0f0442023-08-17 17:06:21 +0800607 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200608 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100609 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
610 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
611 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
612 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
614 RK[7] = RK[1] ^ RK[6];
615 RK[8] = RK[2] ^ RK[7];
616 RK[9] = RK[3] ^ RK[8];
617 RK[10] = RK[4] ^ RK[9];
618 RK[11] = RK[5] ^ RK[10];
619 }
620 break;
621
622 case 14:
623
Jerry Yu3a0f0442023-08-17 17:06:21 +0800624 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200625 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
627 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
628 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
629 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
631 RK[9] = RK[1] ^ RK[8];
632 RK[10] = RK[2] ^ RK[9];
633 RK[11] = RK[3] ^ RK[10];
634
635 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
637 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
638 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
639 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000640
641 RK[13] = RK[5] ^ RK[12];
642 RK[14] = RK[6] ^ RK[13];
643 RK[15] = RK[7] ^ RK[14];
644 }
645 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800646#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000647 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800650#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000651}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200652#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000653
654/*
655 * AES key schedule (decryption)
656 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800657#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100658int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
659 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000660{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800661#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800662 uint32_t *SK;
663#endif
664 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000666 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800667
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000670
Gilles Peskine0de8f852023-03-16 17:14:59 +0100671 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100672 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200674 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200676 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000678
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200679 ctx->nr = cty.nr;
680
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100681#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
683 mbedtls_aesni_inverse_key((unsigned char *) RK,
684 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200685 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100686 }
687#endif
688
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800689#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100690 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800691 mbedtls_aesce_inverse_key(
692 (unsigned char *) RK,
693 (const unsigned char *) (cty.buf + cty.rk_offset),
694 ctx->nr);
695 goto exit;
696 }
697#endif
698
Jerry Yu29c91ba2023-08-04 11:02:04 +0800699#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100700 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000701
702 *RK++ = *SK++;
703 *RK++ = *SK++;
704 *RK++ = *SK++;
705 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800706 SK -= 8;
707 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
708 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
710 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
711 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
712 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000713 }
714 }
715
716 *RK++ = *SK++;
717 *RK++ = *SK++;
718 *RK++ = *SK++;
719 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800720#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200721exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000725}
Yanray Wangb67b4742023-10-31 17:10:32 +0800726#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100727
728#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100729static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
730 unsigned int keybits,
731 const unsigned char **key1,
732 unsigned int *key1bits,
733 const unsigned char **key2,
734 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100735{
736 const unsigned int half_keybits = keybits / 2;
737 const unsigned int half_keybytes = half_keybits / 8;
738
Gilles Peskine449bd832023-01-11 14:50:10 +0100739 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100740 case 256: break;
741 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100743 }
744
745 *key1bits = half_keybits;
746 *key2bits = half_keybits;
747 *key1 = &key[0];
748 *key2 = &key[half_keybytes];
749
750 return 0;
751}
752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
754 const unsigned char *key,
755 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100756{
Janos Follath24eed8d2019-11-22 13:21:35 +0000757 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100758 const unsigned char *key1, *key2;
759 unsigned int key1bits, key2bits;
760
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
762 &key2, &key2bits);
763 if (ret != 0) {
764 return ret;
765 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100766
767 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
769 if (ret != 0) {
770 return ret;
771 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100772
773 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100775}
776
Gilles Peskine449bd832023-01-11 14:50:10 +0100777int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
778 const unsigned char *key,
779 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100780{
Janos Follath24eed8d2019-11-22 13:21:35 +0000781 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100782 const unsigned char *key1, *key2;
783 unsigned int key1bits, key2bits;
784
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
786 &key2, &key2bits);
787 if (ret != 0) {
788 return ret;
789 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100790
791 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
793 if (ret != 0) {
794 return ret;
795 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100796
797 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100799}
800#endif /* MBEDTLS_CIPHER_MODE_XTS */
801
Gilles Peskine449bd832023-01-11 14:50:10 +0100802#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100803 do \
804 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
806 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
807 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
808 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100809 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
811 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
812 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
813 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100814 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
816 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
817 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
818 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100819 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100820 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
821 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
822 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
823 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
824 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100827 do \
828 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
830 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
831 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
832 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100833 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
835 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
836 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
837 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100838 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
840 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
841 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
842 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100843 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
845 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
846 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
847 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
848 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000849
850/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200851 * AES-ECB block encryption
852 */
853#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100854int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
855 const unsigned char input[16],
856 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200857{
858 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100859 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200861 uint32_t X[4];
862 uint32_t Y[4];
863 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200864
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
866 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
867 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
868 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
871 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]);
872 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 +0200873 }
874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 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 +0200876
Gilles Peskine5197c662020-08-26 17:03:24 +0200877 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
879 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
880 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
881 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200882
Gilles Peskine5197c662020-08-26 17:03:24 +0200883 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
885 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
886 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
887 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200888
Gilles Peskine5197c662020-08-26 17:03:24 +0200889 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
891 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
892 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
893 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200894
Gilles Peskine5197c662020-08-26 17:03:24 +0200895 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
897 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
898 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
899 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
902 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
903 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
904 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000905
Gilles Peskine449bd832023-01-11 14:50:10 +0100906 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200909}
910#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
911
912/*
913 * AES-ECB block decryption
914 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800915#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100916int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
917 const unsigned char input[16],
918 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200919{
920 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100921 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200923 uint32_t X[4];
924 uint32_t Y[4];
925 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
928 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
929 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
930 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
933 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]);
934 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 +0200935 }
936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 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 +0200938
Gilles Peskine5197c662020-08-26 17:03:24 +0200939 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
941 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
942 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
943 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200944
Gilles Peskine5197c662020-08-26 17:03:24 +0200945 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
947 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
948 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
949 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200950
Gilles Peskine5197c662020-08-26 17:03:24 +0200951 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
953 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
954 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
955 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200956
Gilles Peskine5197c662020-08-26 17:03:24 +0200957 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
959 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
960 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
961 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
964 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
965 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
966 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200971}
Yanray Wangb67b4742023-10-31 17:10:32 +0800972#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Thomas Daubney62af02c2024-06-14 10:37:13 +0100974/*
975 * Our intrinsics-based implementation of AESNI require the round keys to be
976 * aligned on a 16-byte boundary. We take care of this before creating them,
977 * but the AES context may have moved (this can happen if the library is
978 * called from a language with managed memory), and in later calls it might
979 * have a different alignment with respect to 16-byte memory. So we may need
980 * to realign.
Gilles Peskine148cad12023-03-16 13:08:42 +0100981 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100982MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +0100983{
Thomas Daubney6a758fc2024-06-20 16:43:20 +0100984#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100985 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
986 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +0100987 memmove(ctx->buf + new_offset, // new address
988 ctx->buf + ctx->rk_offset, // current address
989 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
990 ctx->rk_offset = new_offset;
991 }
Thomas Daubney6a758fc2024-06-20 16:43:20 +0100992#endif /* MAY_NEED_TO_ALIGN */
993 (void) ctx;
Gilles Peskine148cad12023-03-16 13:08:42 +0100994}
Gilles Peskine148cad12023-03-16 13:08:42 +0100995
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000997 * AES-ECB block encryption/decryption
998 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100999int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1000 int mode,
1001 const unsigned char input[16],
1002 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001003{
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001005 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001007
Gilles Peskine0de8f852023-03-16 17:14:59 +01001008#if defined(MAY_NEED_TO_ALIGN)
1009 aes_maybe_realign(ctx);
1010#endif
1011
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001012#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1014 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1015 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001016#endif
1017
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001018#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001019 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001020 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1021 }
1022#endif
1023
Jerry Yu29c91ba2023-08-04 11:02:04 +08001024#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001025#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang111159b2023-11-10 13:41:12 +08001026 if (mode == MBEDTLS_AES_DECRYPT) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang111159b2023-11-10 13:41:12 +08001028 } else
Jerry Yu29c91ba2023-08-04 11:02:04 +08001029#endif
Yanray Wang111159b2023-11-10 13:41:12 +08001030 {
1031 return mbedtls_internal_aes_encrypt(ctx, input, output);
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001032 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001033#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001034}
1035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001037
Paul Bakker5121ce52009-01-03 21:22:43 +00001038/*
1039 * AES-CBC buffer encryption/decryption
1040 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001041int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1042 int mode,
1043 size_t length,
1044 unsigned char iv[16],
1045 const unsigned char *input,
1046 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001047{
Gilles Peskine7820a572021-07-07 21:08:28 +02001048 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001049 unsigned char temp[16];
1050
Gilles Peskine449bd832023-01-11 14:50:10 +01001051 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001052 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001054
Paul Elliott2ad93672023-08-11 11:07:06 +01001055 /* Nothing to do if length is zero. */
1056 if (length == 0) {
1057 return 0;
1058 }
1059
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 if (length % 16) {
1061 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1062 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001063
Dave Rodgman906c63c2023-06-14 17:53:51 +01001064 const unsigned char *ivp = iv;
1065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (mode == MBEDTLS_AES_DECRYPT) {
1067 while (length > 0) {
1068 memcpy(temp, input, 16);
1069 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1070 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001071 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001073 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001074 * the result for the next block in CBC, and the cost of transferring that data from
1075 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001076 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001077
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001079
1080 input += 16;
1081 output += 16;
1082 length -= 16;
1083 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 } else {
1085 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001086 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001087
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1089 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001090 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001092 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001093
1094 input += 16;
1095 output += 16;
1096 length -= 16;
1097 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001098 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001099 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001100 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001101
Gilles Peskine7820a572021-07-07 21:08:28 +02001102exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001104}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001105#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001106
Aorimn5f778012016-06-09 23:22:58 +02001107#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001108
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001109typedef unsigned char mbedtls_be128[16];
1110
1111/*
1112 * GF(2^128) multiplication function
1113 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001114 * This function multiplies a field element by x in the polynomial field
1115 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001116 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001117 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001118 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001119#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001120MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001121#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001122static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001123 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001124{
1125 uint64_t a, b, ra, rb;
1126
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 a = MBEDTLS_GET_UINT64_LE(x, 0);
1128 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1131 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1134 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001135}
1136
Aorimn5f778012016-06-09 23:22:58 +02001137/*
1138 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001139 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001140 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001141 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001142 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001143#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001144MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001145#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001146int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1147 int mode,
1148 size_t length,
1149 const unsigned char data_unit[16],
1150 const unsigned char *input,
1151 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001152{
Janos Follath24eed8d2019-11-22 13:21:35 +00001153 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001154 size_t blocks = length / 16;
1155 size_t leftover = length % 16;
1156 unsigned char tweak[16];
1157 unsigned char prev_tweak[16];
1158 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001159
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001161 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001163
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001164 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001166 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 }
Aorimn5f778012016-06-09 23:22:58 +02001168
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001169 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001171 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 }
Aorimn5f778012016-06-09 23:22:58 +02001173
Jaeden Amerod82cd862018-04-28 15:02:45 +01001174 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1176 data_unit, tweak);
1177 if (ret != 0) {
1178 return ret;
1179 }
Aorimn5f778012016-06-09 23:22:58 +02001180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001182 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001183 /* We are on the last block in a decrypt operation that has
1184 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001185 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001186 * the leftovers and then update the current tweak for use on this,
1187 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001188 memcpy(prev_tweak, tweak, sizeof(tweak));
1189 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001190 }
1191
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001193
Gilles Peskine449bd832023-01-11 14:50:10 +01001194 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1195 if (ret != 0) {
1196 return ret;
1197 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001198
Gilles Peskine449bd832023-01-11 14:50:10 +01001199 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001200
1201 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001203
1204 output += 16;
1205 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001206 }
1207
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001209 /* If we are on the leftover bytes in a decrypt operation, we need to
1210 * use the previous tweak for these bytes (as saved in prev_tweak). */
1211 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001212
Jaeden Amerod82cd862018-04-28 15:02:45 +01001213 /* We are now on the final part of the data unit, which doesn't divide
1214 * evenly by 16. It's time for ciphertext stealing. */
1215 size_t i;
1216 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001217
Jaeden Amerod82cd862018-04-28 15:02:45 +01001218 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001219 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001222 }
Aorimn5f778012016-06-09 23:22:58 +02001223
Dave Rodgman069e7f42022-11-24 19:37:26 +00001224 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001226
Jaeden Amerod82cd862018-04-28 15:02:45 +01001227 /* Copy ciphertext bytes from the previous block for input in this
1228 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001230
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1232 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001233 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 }
Aorimn5f778012016-06-09 23:22:58 +02001235
Jaeden Amerod82cd862018-04-28 15:02:45 +01001236 /* Write the result back to the previous block, overriding the previous
1237 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001238 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001239 }
1240
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001242}
1243#endif /* MBEDTLS_CIPHER_MODE_XTS */
1244
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001245#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001246/*
1247 * AES-CFB128 buffer encryption/decryption
1248 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001249int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1250 int mode,
1251 size_t length,
1252 size_t *iv_off,
1253 unsigned char iv[16],
1254 const unsigned char *input,
1255 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001256{
Paul Bakker27fdf462011-06-09 13:55:13 +00001257 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001258 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001259 size_t n;
1260
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001262 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001264
1265 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001266
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 if (n > 15) {
1268 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1269 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001270
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 if (mode == MBEDTLS_AES_DECRYPT) {
1272 while (length--) {
1273 if (n == 0) {
1274 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1275 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001276 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001278 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001279
1280 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001282 iv[n] = (unsigned char) c;
1283
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001285 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 } else {
1287 while (length--) {
1288 if (n == 0) {
1289 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1290 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001291 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001293 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001296
Gilles Peskine449bd832023-01-11 14:50:10 +01001297 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001298 }
1299 }
1300
1301 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001302 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001303
Gilles Peskine7820a572021-07-07 21:08:28 +02001304exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001305 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001306}
Paul Bakker556efba2014-01-24 15:38:12 +01001307
1308/*
1309 * AES-CFB8 buffer encryption/decryption
1310 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001311int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1312 int mode,
1313 size_t length,
1314 unsigned char iv[16],
1315 const unsigned char *input,
1316 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001317{
Gilles Peskine7820a572021-07-07 21:08:28 +02001318 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001319 unsigned char c;
1320 unsigned char ov[17];
1321
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001323 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 }
1325 while (length--) {
1326 memcpy(ov, iv, 16);
1327 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1328 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001329 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 }
Paul Bakker556efba2014-01-24 15:38:12 +01001331
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001333 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 }
Paul Bakker556efba2014-01-24 15:38:12 +01001335
Gilles Peskine449bd832023-01-11 14:50:10 +01001336 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001337
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001339 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 }
Paul Bakker556efba2014-01-24 15:38:12 +01001341
Gilles Peskine449bd832023-01-11 14:50:10 +01001342 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001343 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001344 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001345
Gilles Peskine7820a572021-07-07 21:08:28 +02001346exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001348}
Simon Butcher76a5b222018-04-22 22:57:27 +01001349#endif /* MBEDTLS_CIPHER_MODE_CFB */
1350
1351#if defined(MBEDTLS_CIPHER_MODE_OFB)
1352/*
1353 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1354 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001355int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1356 size_t length,
1357 size_t *iv_off,
1358 unsigned char iv[16],
1359 const unsigned char *input,
1360 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001361{
Simon Butcherad4e4932018-04-29 00:43:47 +01001362 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001363 size_t n;
1364
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001365 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001366
Gilles Peskine449bd832023-01-11 14:50:10 +01001367 if (n > 15) {
1368 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1369 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001370
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 while (length--) {
1372 if (n == 0) {
1373 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1374 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001375 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001377 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001378 *output++ = *input++ ^ iv[n];
1379
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001381 }
1382
1383 *iv_off = n;
1384
Simon Butcherad4e4932018-04-29 00:43:47 +01001385exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001387}
1388#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001390#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001391/*
1392 * AES-CTR buffer encryption/decryption
1393 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001394int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1395 size_t length,
1396 size_t *nc_off,
1397 unsigned char nonce_counter[16],
1398 unsigned char stream_block[16],
1399 const unsigned char *input,
1400 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001401{
Gilles Peskine7820a572021-07-07 21:08:28 +02001402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001403
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001404 size_t offset = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001405
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001406 if (offset > 0x0F) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001407 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1408 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001409
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001410 for (size_t i = 0; i < length;) {
1411 size_t n = 16;
1412 if (offset == 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001413 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1414 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001415 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 }
Dave Rodgman591ff052024-01-13 16:42:38 +00001417 mbedtls_ctr_increment_counter(nonce_counter);
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001418 } else {
1419 n -= offset;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001420 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001421
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001422 if (n > (length - i)) {
1423 n = (length - i);
1424 }
1425 mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
1426 // offset might be non-zero for the last block, but in that case, we don't use it again
1427 offset = 0;
1428 i += n;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001429 }
1430
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001431 // capture offset for future resumption
1432 *nc_off = (*nc_off + length) % 16;
1433
Gilles Peskine7820a572021-07-07 21:08:28 +02001434 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001435
Gilles Peskine7820a572021-07-07 21:08:28 +02001436exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001438}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001439#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001440
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001441#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001444/*
1445 * AES test vectors from:
1446 *
1447 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1448 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001449#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001450static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001451{
1452 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1453 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001454#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001455 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1456 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1457 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1458 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001459#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001460};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001461#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001462
Yanray Wang62c99912023-05-11 11:06:53 +08001463static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001464{
1465 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1466 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001467#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001468 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1469 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1470 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1471 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001472#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001473};
1474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001475#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001476static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001477{
1478 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1479 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001480#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001481 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1482 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1483 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1484 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001485#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001486};
1487
Yanray Wang62c99912023-05-11 11:06:53 +08001488static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001489{
1490 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1491 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001492#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001493 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1494 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1495 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1496 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001497#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001498};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001499#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001501#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001502/*
1503 * AES-CFB128 test vectors from:
1504 *
1505 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1506 */
Yanray Wang62c99912023-05-11 11:06:53 +08001507static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001508{
1509 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1510 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001511#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001512 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1513 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1514 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1515 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1516 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1517 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1518 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001519#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001520};
1521
1522static const unsigned char aes_test_cfb128_iv[16] =
1523{
1524 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1525 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1526};
1527
1528static const unsigned char aes_test_cfb128_pt[64] =
1529{
1530 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1531 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1532 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1533 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1534 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1535 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1536 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1537 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1538};
1539
Yanray Wang62c99912023-05-11 11:06:53 +08001540static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001541{
1542 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1543 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1544 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1545 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1546 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1547 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1548 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1549 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001550#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001551 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1552 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1553 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1554 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1555 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1556 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1557 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1558 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1559 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1560 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1561 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1562 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1563 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1564 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1565 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1566 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001567#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001568};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001569#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001570
Simon Butcherad4e4932018-04-29 00:43:47 +01001571#if defined(MBEDTLS_CIPHER_MODE_OFB)
1572/*
1573 * AES-OFB test vectors from:
1574 *
Simon Butcher5db13622018-06-04 22:11:25 +01001575 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001576 */
Yanray Wang62c99912023-05-11 11:06:53 +08001577static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001578{
1579 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1580 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001581#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001582 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1583 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1584 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1585 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1586 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1587 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1588 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001589#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001590};
1591
1592static const unsigned char aes_test_ofb_iv[16] =
1593{
1594 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1595 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1596};
1597
1598static const unsigned char aes_test_ofb_pt[64] =
1599{
1600 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1601 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1602 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1603 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1604 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1605 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1606 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1607 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1608};
1609
Yanray Wang62c99912023-05-11 11:06:53 +08001610static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001611{
1612 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1613 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1614 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1615 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1616 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1617 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1618 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1619 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001620#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001621 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1622 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1623 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1624 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1625 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1626 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1627 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1628 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1629 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1630 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1631 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1632 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1633 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1634 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1635 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1636 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001637#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001638};
1639#endif /* MBEDTLS_CIPHER_MODE_OFB */
1640
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001641#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001642/*
1643 * AES-CTR test vectors from:
1644 *
1645 * http://www.faqs.org/rfcs/rfc3686.html
1646 */
1647
Yanray Wang62c99912023-05-11 11:06:53 +08001648static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001649{
1650 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1651 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1652 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1653 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1654 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1655 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1656};
1657
Yanray Wang62c99912023-05-11 11:06:53 +08001658static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001659{
1660 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1662 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1663 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1664 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1665 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1666};
1667
Yanray Wang62c99912023-05-11 11:06:53 +08001668static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001669{
1670 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1671 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001672 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1673 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1674 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1675 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1676
1677 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1678 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1679 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1680 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1681 0x20, 0x21, 0x22, 0x23 }
1682};
1683
Yanray Wang62c99912023-05-11 11:06:53 +08001684static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001685{
1686 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1687 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1688 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1689 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1690 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1691 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1692 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1693 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1694 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1695 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1696 0x25, 0xB2, 0x07, 0x2F }
1697};
1698
1699static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001700{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001701#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001702
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001703#if defined(MBEDTLS_CIPHER_MODE_XTS)
1704/*
1705 * AES-XTS test vectors from:
1706 *
1707 * IEEE P1619/D16 Annex B
1708 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1709 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1710 */
1711static const unsigned char aes_test_xts_key[][32] =
1712{
1713 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1717 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1718 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1719 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1720 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1721 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1722 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1723 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1724 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1725};
1726
1727static const unsigned char aes_test_xts_pt32[][32] =
1728{
1729 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1733 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1734 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1735 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1736 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1737 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1738 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1739 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1740 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1741};
1742
1743static const unsigned char aes_test_xts_ct32[][32] =
1744{
1745 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1746 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1747 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1748 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1749 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1750 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1751 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1752 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1753 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1754 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1755 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1756 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1757};
1758
1759static const unsigned char aes_test_xts_data_unit[][16] =
1760{
Gilles Peskine449bd832023-01-11 14:50:10 +01001761 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1762 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1763 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1765 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001767};
1768
1769#endif /* MBEDTLS_CIPHER_MODE_XTS */
1770
Paul Bakker5121ce52009-01-03 21:22:43 +00001771/*
1772 * Checkup routine
1773 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001774int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001775{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001776 int ret = 0, i, j, u, mode;
1777 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001778 unsigned char key[32];
1779 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001780 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001781#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1782 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001783 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001784#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001785#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001786 unsigned char prv[16];
1787#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001788#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1789 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001790 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001791#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001792#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001793 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001794#endif
1795#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001796 unsigned char nonce_counter[16];
1797 unsigned char stream_block[16];
1798#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001799 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001800
Gilles Peskine449bd832023-01-11 14:50:10 +01001801 memset(key, 0, 32);
1802 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001803
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001804 if (verbose != 0) {
1805#if defined(MBEDTLS_AES_ALT)
1806 mbedtls_printf(" AES note: alternative implementation.\n");
1807#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001808#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001809#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001810 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001811#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001812 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001813#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001814#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001815#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001816 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1817 mbedtls_printf(" AES note: using AESNI.\n");
1818 } else
1819#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001820#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001821 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001822 mbedtls_printf(" AES note: using AESCE.\n");
1823 } else
1824#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001825 {
1826#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1827 mbedtls_printf(" AES note: built-in implementation.\n");
1828#endif
1829 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001830#endif /* MBEDTLS_AES_ALT */
1831 }
1832
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 /*
1834 * ECB mode
1835 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001836 {
1837 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001838 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001839
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001840 for (i = 0; i < num_tests << 1; i++) {
1841 u = i >> 1;
1842 keybits = 128 + u * 64;
1843 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001844
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001845 if (verbose != 0) {
1846 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1847 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1848 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001849#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001850 if (mode == MBEDTLS_AES_DECRYPT) {
1851 if (verbose != 0) {
1852 mbedtls_printf("skipped\n");
1853 }
1854 continue;
1855 }
1856#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001857
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001858 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001859
Yanray Wangb67b4742023-10-31 17:10:32 +08001860#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001861 if (mode == MBEDTLS_AES_DECRYPT) {
1862 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1863 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001864 } else
1865#endif
1866 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001867 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1868 aes_tests = aes_test_ecb_enc[u];
1869 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001870
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001871 /*
1872 * AES-192 is an optional feature that may be unavailable when
1873 * there is an alternative underlying implementation i.e. when
1874 * MBEDTLS_AES_ALT is defined.
1875 */
1876 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1877 mbedtls_printf("skipped\n");
1878 continue;
1879 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001880 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001881 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001882
1883 for (j = 0; j < 10000; j++) {
1884 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1885 if (ret != 0) {
1886 goto exit;
1887 }
1888 }
1889
1890 if (memcmp(buf, aes_tests, 16) != 0) {
1891 ret = 1;
1892 goto exit;
1893 }
1894
1895 if (verbose != 0) {
1896 mbedtls_printf("passed\n");
1897 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001898 }
1899
Gilles Peskine449bd832023-01-11 14:50:10 +01001900 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001901 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001902 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 }
1904
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001905#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001906 /*
1907 * CBC mode
1908 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001909 {
1910 static const int num_tests =
1911 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001912
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001913 for (i = 0; i < num_tests << 1; i++) {
1914 u = i >> 1;
1915 keybits = 128 + u * 64;
1916 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001917
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001918 if (verbose != 0) {
1919 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1920 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001921 }
1922
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001923 memset(iv, 0, 16);
1924 memset(prv, 0, 16);
1925 memset(buf, 0, 16);
1926
1927 if (mode == MBEDTLS_AES_DECRYPT) {
1928 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1929 aes_tests = aes_test_cbc_dec[u];
1930 } else {
1931 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1932 aes_tests = aes_test_cbc_enc[u];
1933 }
1934
1935 /*
1936 * AES-192 is an optional feature that may be unavailable when
1937 * there is an alternative underlying implementation i.e. when
1938 * MBEDTLS_AES_ALT is defined.
1939 */
1940 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1941 mbedtls_printf("skipped\n");
1942 continue;
1943 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001944 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001945 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001946
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001947 for (j = 0; j < 10000; j++) {
1948 if (mode == MBEDTLS_AES_ENCRYPT) {
1949 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001950
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001951 memcpy(tmp, prv, 16);
1952 memcpy(prv, buf, 16);
1953 memcpy(buf, tmp, 16);
1954 }
1955
1956 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1957 if (ret != 0) {
1958 goto exit;
1959 }
1960
1961 }
1962
1963 if (memcmp(buf, aes_tests, 16) != 0) {
1964 ret = 1;
1965 goto exit;
1966 }
1967
1968 if (verbose != 0) {
1969 mbedtls_printf("passed\n");
1970 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001971 }
1972
Gilles Peskine449bd832023-01-11 14:50:10 +01001973 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001974 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001975 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001976 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001977#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001978
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001979#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001980 /*
1981 * CFB128 mode
1982 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001983 {
1984 static const int num_tests =
1985 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00001986
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001987 for (i = 0; i < num_tests << 1; i++) {
1988 u = i >> 1;
1989 keybits = 128 + u * 64;
1990 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001991
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001992 if (verbose != 0) {
1993 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1994 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1995 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001996
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001997 memcpy(iv, aes_test_cfb128_iv, 16);
1998 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001999
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002000 offset = 0;
2001 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2002 /*
2003 * AES-192 is an optional feature that may be unavailable when
2004 * there is an alternative underlying implementation i.e. when
2005 * MBEDTLS_AES_ALT is defined.
2006 */
2007 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2008 mbedtls_printf("skipped\n");
2009 continue;
2010 } else if (ret != 0) {
2011 goto exit;
2012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002013
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002014 if (mode == MBEDTLS_AES_DECRYPT) {
2015 memcpy(buf, aes_test_cfb128_ct[u], 64);
2016 aes_tests = aes_test_cfb128_pt;
2017 } else {
2018 memcpy(buf, aes_test_cfb128_pt, 64);
2019 aes_tests = aes_test_cfb128_ct[u];
2020 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002021
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002022 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2023 if (ret != 0) {
2024 goto exit;
2025 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002026
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002027 if (memcmp(buf, aes_tests, 64) != 0) {
2028 ret = 1;
2029 goto exit;
2030 }
2031
2032 if (verbose != 0) {
2033 mbedtls_printf("passed\n");
2034 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002035 }
2036
Gilles Peskine449bd832023-01-11 14:50:10 +01002037 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002038 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002039 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002040 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002041#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002042
Simon Butcherad4e4932018-04-29 00:43:47 +01002043#if defined(MBEDTLS_CIPHER_MODE_OFB)
2044 /*
2045 * OFB mode
2046 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002047 {
2048 static const int num_tests =
2049 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002050
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002051 for (i = 0; i < num_tests << 1; i++) {
2052 u = i >> 1;
2053 keybits = 128 + u * 64;
2054 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002055
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002056 if (verbose != 0) {
2057 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2058 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2059 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002060
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002061 memcpy(iv, aes_test_ofb_iv, 16);
2062 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002063
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002064 offset = 0;
2065 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2066 /*
2067 * AES-192 is an optional feature that may be unavailable when
2068 * there is an alternative underlying implementation i.e. when
2069 * MBEDTLS_AES_ALT is defined.
2070 */
2071 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2072 mbedtls_printf("skipped\n");
2073 continue;
2074 } else if (ret != 0) {
2075 goto exit;
2076 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002077
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002078 if (mode == MBEDTLS_AES_DECRYPT) {
2079 memcpy(buf, aes_test_ofb_ct[u], 64);
2080 aes_tests = aes_test_ofb_pt;
2081 } else {
2082 memcpy(buf, aes_test_ofb_pt, 64);
2083 aes_tests = aes_test_ofb_ct[u];
2084 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002085
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002086 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2087 if (ret != 0) {
2088 goto exit;
2089 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002090
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002091 if (memcmp(buf, aes_tests, 64) != 0) {
2092 ret = 1;
2093 goto exit;
2094 }
2095
2096 if (verbose != 0) {
2097 mbedtls_printf("passed\n");
2098 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002099 }
2100
Gilles Peskine449bd832023-01-11 14:50:10 +01002101 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002102 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002103 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002104 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002105#endif /* MBEDTLS_CIPHER_MODE_OFB */
2106
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002107#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002108 /*
2109 * CTR mode
2110 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002111 {
2112 static const int num_tests =
2113 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002114
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002115 for (i = 0; i < num_tests << 1; i++) {
2116 u = i >> 1;
2117 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002118
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002119 if (verbose != 0) {
2120 mbedtls_printf(" AES-CTR-128 (%s): ",
2121 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2122 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002123
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002124 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2125 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002126
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002127 offset = 0;
2128 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2129 goto exit;
2130 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002131
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002132 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002133
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002134 if (mode == MBEDTLS_AES_DECRYPT) {
2135 memcpy(buf, aes_test_ctr_ct[u], len);
2136 aes_tests = aes_test_ctr_pt[u];
2137 } else {
2138 memcpy(buf, aes_test_ctr_pt[u], len);
2139 aes_tests = aes_test_ctr_ct[u];
2140 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002141
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002142 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2143 stream_block, buf, buf);
2144 if (ret != 0) {
2145 goto exit;
2146 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002147
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002148 if (memcmp(buf, aes_tests, len) != 0) {
2149 ret = 1;
2150 goto exit;
2151 }
2152
2153 if (verbose != 0) {
2154 mbedtls_printf("passed\n");
2155 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002156 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002157 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002158
Gilles Peskine449bd832023-01-11 14:50:10 +01002159 if (verbose != 0) {
2160 mbedtls_printf("\n");
2161 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002162#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002163
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002164#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002165 /*
2166 * XTS mode
2167 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002168 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002169 static const int num_tests =
2170 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2171 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002172
Gilles Peskine449bd832023-01-11 14:50:10 +01002173 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002174
Gilles Peskine449bd832023-01-11 14:50:10 +01002175 for (i = 0; i < num_tests << 1; i++) {
2176 const unsigned char *data_unit;
2177 u = i >> 1;
2178 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002179
Gilles Peskine449bd832023-01-11 14:50:10 +01002180 if (verbose != 0) {
2181 mbedtls_printf(" AES-XTS-128 (%s): ",
2182 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2183 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002184
Gilles Peskine449bd832023-01-11 14:50:10 +01002185 memset(key, 0, sizeof(key));
2186 memcpy(key, aes_test_xts_key[u], 32);
2187 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002188
Gilles Peskine449bd832023-01-11 14:50:10 +01002189 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002190
Gilles Peskine449bd832023-01-11 14:50:10 +01002191 if (mode == MBEDTLS_AES_DECRYPT) {
2192 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2193 if (ret != 0) {
2194 goto exit;
2195 }
2196 memcpy(buf, aes_test_xts_ct32[u], len);
2197 aes_tests = aes_test_xts_pt32[u];
2198 } else {
2199 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2200 if (ret != 0) {
2201 goto exit;
2202 }
2203 memcpy(buf, aes_test_xts_pt32[u], len);
2204 aes_tests = aes_test_xts_ct32[u];
2205 }
2206
2207
2208 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2209 buf, buf);
2210 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002211 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002212 }
2213
2214 if (memcmp(buf, aes_tests, len) != 0) {
2215 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002216 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002217 }
2218
2219 if (verbose != 0) {
2220 mbedtls_printf("passed\n");
2221 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002222 }
2223
Gilles Peskine449bd832023-01-11 14:50:10 +01002224 if (verbose != 0) {
2225 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002226 }
2227
Gilles Peskine449bd832023-01-11 14:50:10 +01002228 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002229 }
2230#endif /* MBEDTLS_CIPHER_MODE_XTS */
2231
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002232 ret = 0;
2233
2234exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002235 if (ret != 0 && verbose != 0) {
2236 mbedtls_printf("failed\n");
2237 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002238
Gilles Peskine449bd832023-01-11 14:50:10 +01002239 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002240
Gilles Peskine449bd832023-01-11 14:50:10 +01002241 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002242}
2243
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002244#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002246#endif /* MBEDTLS_AES_C */