blob: 0f96db0b32b72c03985428848496022935108034 [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 */
Thomas Daubneyb59c0ba2024-07-24 18:10:24 +010047#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wangdbcc0c62023-08-30 15:04:01 +080048#define MBEDTLS_AES_NEED_REVERSE_TABLES
49#endif
50
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000052/*
53 * Forward S-box
54 */
Dave Rodgman18ddf612023-10-04 14:03:12 +010055MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +000056{
57 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
58 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
59 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
60 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
61 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
62 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
63 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
64 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
65 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
66 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
67 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
68 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
69 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
70 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
71 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
72 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
73 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
74 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
75 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
76 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
77 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
78 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
79 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
80 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
81 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
82 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
83 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
84 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
85 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
86 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
87 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
88 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
89};
90
91/*
92 * Forward tables
93 */
94#define FT \
95\
Gilles Peskine449bd832023-01-11 14:50:10 +010096 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
97 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
98 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
99 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
100 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
101 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
102 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
103 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
104 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
105 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
106 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
107 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
108 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
109 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
110 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
111 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
112 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
113 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
114 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
115 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
116 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
117 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
118 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
119 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
120 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
121 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
122 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
123 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
124 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
125 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
126 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
127 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
128 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
129 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
130 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
131 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
132 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
133 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
134 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
135 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
136 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
137 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
138 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
139 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
140 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
141 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
142 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
143 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
144 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
145 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
146 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
147 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
148 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
149 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
150 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
151 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
152 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
153 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
154 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
155 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
156 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
157 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
158 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
159 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 +0000160
Gilles Peskine449bd832023-01-11 14:50:10 +0100161#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100162MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000163#undef V
164
Gilles Peskine449bd832023-01-11 14:50:10 +0100165#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100166MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[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##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100170MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[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##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100174MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000175#undef V
176
177#undef FT
178
179/*
180 * Reverse S-box
181 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100182MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000183{
184 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
185 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
186 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
187 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
188 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
189 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
190 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
191 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
192 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
193 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
194 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
195 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
196 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
197 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
198 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
199 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
200 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
201 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
202 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
203 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
204 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
205 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
206 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
207 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
208 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
209 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
210 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
211 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
212 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
213 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
214 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
215 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
216};
217
218/*
219 * Reverse tables
220 */
221#define RT \
222\
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
224 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
225 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
226 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
227 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
228 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
229 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
230 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
231 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
232 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
233 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
234 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
235 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
236 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
237 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
238 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
239 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
240 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
241 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
242 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
243 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
244 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
245 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
246 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
247 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
248 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
249 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
250 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
251 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
252 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
253 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
254 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
255 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
256 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
257 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
258 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
259 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
260 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
261 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
262 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
263 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
264 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
265 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
266 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
267 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
268 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
269 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
270 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
271 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
272 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
273 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
274 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
275 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
276 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
277 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
278 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
279 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
280 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
281 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
282 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
283 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
284 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
285 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
286 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 +0000287
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100290MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000291#undef V
292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100294MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[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##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100298MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[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##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100302MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000303#undef V
304
305#undef RT
306
307/*
308 * Round constants
309 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100310MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000311{
312 0x00000001, 0x00000002, 0x00000004, 0x00000008,
313 0x00000010, 0x00000020, 0x00000040, 0x00000080,
314 0x0000001B, 0x00000036
315};
316
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
319/*
320 * Forward S-box & tables
321 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100322MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
323MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
324MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
325MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
326MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000327
328/*
329 * Reverse S-box & tables
330 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100331MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100332
Dave Rodgman18ddf612023-10-04 14:03:12 +0100333MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
334MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
335MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
336MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
338/*
339 * Round constants
340 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100341MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000342
343/*
344 * Tables generation code
345 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100346#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
347#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
348#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000349
Dave Rodgman18ddf612023-10-04 14:03:12 +0100350MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
Dave Rodgman18ddf612023-10-04 14:03:12 +0100352MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000353{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800354 int i;
355 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800356 uint8_t pow[256];
357 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000358
359 /*
360 * compute pow and log tables over GF(2^8)
361 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000363 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800364 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800365 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000366 }
367
368 /*
369 * calculate the round constants
370 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200372 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800373 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000374 }
375
376 /*
377 * generate the forward and reverse S-boxes
378 */
379 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800380#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000381 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800382#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000385 x = pow[255 - log[i]];
386
Yanray Wangfe944ce2023-06-26 18:16:01 +0800387 y = x; y = (y << 1) | (y >> 7);
388 x ^= y; y = (y << 1) | (y >> 7);
389 x ^= y; y = (y << 1) | (y >> 7);
390 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000391 x ^= y ^ 0x63;
392
Yanray Wangfe944ce2023-06-26 18:16:01 +0800393 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800394#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800396#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000397 }
398
399 /*
400 * generate the forward and reverse tables
401 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800404 y = XTIME(x);
405 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 FT0[i] = ((uint32_t) y) ^
408 ((uint32_t) x << 8) ^
409 ((uint32_t) x << 16) ^
410 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
Hanno Beckerad049a92017-06-19 16:31:54 +0100412#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 FT1[i] = ROTL8(FT0[i]);
414 FT2[i] = ROTL8(FT1[i]);
415 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100416#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800418#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 x = RSb[i];
420
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
422 ((uint32_t) MUL(0x09, x) << 8) ^
423 ((uint32_t) MUL(0x0D, x) << 16) ^
424 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
Hanno Beckerad049a92017-06-19 16:31:54 +0100426#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 RT1[i] = ROTL8(RT0[i]);
428 RT2[i] = ROTL8(RT1[i]);
429 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100430#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800431#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 }
433}
434
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200435#undef ROTL8
436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
Hanno Beckerad049a92017-06-19 16:31:54 +0100439#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200440
Gilles Peskine449bd832023-01-11 14:50:10 +0100441#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
442#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
443#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200444
445#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100446#define AES_RT1(idx) ROTL8(RT0[idx])
447#define AES_RT2(idx) ROTL16(RT0[idx])
448#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200449
450#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100451#define AES_FT1(idx) ROTL8(FT0[idx])
452#define AES_FT2(idx) ROTL16(FT0[idx])
453#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200454
Hanno Becker177d3cf2017-06-07 15:52:48 +0100455#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200456
457#define AES_RT0(idx) RT0[idx]
458#define AES_RT1(idx) RT1[idx]
459#define AES_RT2(idx) RT2[idx]
460#define AES_RT3(idx) RT3[idx]
461
462#define AES_FT0(idx) FT0[idx]
463#define AES_FT1(idx) FT1[idx]
464#define AES_FT2(idx) FT2[idx]
465#define AES_FT3(idx) FT3[idx]
466
Hanno Becker177d3cf2017-06-07 15:52:48 +0100467#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200468
Gilles Peskine449bd832023-01-11 14:50:10 +0100469void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200470{
Gilles Peskine449bd832023-01-11 14:50:10 +0100471 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200472}
473
Gilles Peskine449bd832023-01-11 14:50:10 +0100474void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200475{
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200477 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200481}
482
Jaeden Amero9366feb2018-05-29 18:55:17 +0100483#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100484void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100485{
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 mbedtls_aes_init(&ctx->crypt);
487 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100488}
489
Gilles Peskine449bd832023-01-11 14:50:10 +0100490void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100491{
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100493 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 }
Simon Butcher5201e412018-12-06 17:40:14 +0000495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 mbedtls_aes_free(&ctx->crypt);
497 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100498}
499#endif /* MBEDTLS_CIPHER_MODE_XTS */
500
Gilles Peskine0de8f852023-03-16 17:14:59 +0100501/* Some implementations need the round keys to be aligned.
502 * Return an offset to be added to buf, such that (buf + offset) is
503 * correctly aligned.
504 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
505 * i.e. an offset of 1 means 4 bytes and so on.
506 */
Thomas Daubneyf57a3522024-06-25 15:23:57 +0100507#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100508#define MAY_NEED_TO_ALIGN
509#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100510
Dave Rodgman18ddf612023-10-04 14:03:12 +0100511MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100512{
513#if defined(MAY_NEED_TO_ALIGN)
514 int align_16_bytes = 0;
515
Gilles Peskine9c682e72023-03-16 17:21:33 +0100516#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100517 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
518 align_16_bytes = 1;
519 }
520#endif
521
522 if (align_16_bytes) {
523 /* These implementations needs 16-byte alignment
524 * for the round key array. */
525 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
526 if (delta == 0) {
527 return 0;
528 } else {
529 return 4 - delta; // 16 bytes = 4 uint32_t
530 }
531 }
532#else /* MAY_NEED_TO_ALIGN */
533 (void) buf;
534#endif /* MAY_NEED_TO_ALIGN */
535
536 return 0;
537}
538
Paul Bakker5121ce52009-01-03 21:22:43 +0000539/*
540 * AES key schedule (encryption)
541 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100542int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
543 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000544{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000545 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000546
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000548 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800549#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000550 case 192: ctx->nr = 12; break;
551 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800552#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000554 }
555
Simon Butcher5201e412018-12-06 17:40:14 +0000556#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000558 aes_gen_tables();
559 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000560 }
561#endif
562
Gilles Peskine0de8f852023-03-16 17:14:59 +0100563 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100564 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100566#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
568 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
569 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100570#endif
571
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800572#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100573 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800574 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
575 }
576#endif
577
Jerry Yu29c91ba2023-08-04 11:02:04 +0800578#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800579 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100580 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000581 }
582
Gilles Peskine449bd832023-01-11 14:50:10 +0100583 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 case 10:
585
Jerry Yu3a0f0442023-08-17 17:06:21 +0800586 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200587 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
589 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
590 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
591 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000592
593 RK[5] = RK[1] ^ RK[4];
594 RK[6] = RK[2] ^ RK[5];
595 RK[7] = RK[3] ^ RK[6];
596 }
597 break;
598
Arto Kinnunen732ca322023-04-14 14:26:10 +0800599#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000600 case 12:
601
Jerry Yu3a0f0442023-08-17 17:06:21 +0800602 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200603 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
605 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
606 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
607 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
609 RK[7] = RK[1] ^ RK[6];
610 RK[8] = RK[2] ^ RK[7];
611 RK[9] = RK[3] ^ RK[8];
612 RK[10] = RK[4] ^ RK[9];
613 RK[11] = RK[5] ^ RK[10];
614 }
615 break;
616
617 case 14:
618
Jerry Yu3a0f0442023-08-17 17:06:21 +0800619 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200620 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
622 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
623 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
624 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
626 RK[9] = RK[1] ^ RK[8];
627 RK[10] = RK[2] ^ RK[9];
628 RK[11] = RK[3] ^ RK[10];
629
630 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100631 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
632 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
633 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
634 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
636 RK[13] = RK[5] ^ RK[12];
637 RK[14] = RK[6] ^ RK[13];
638 RK[15] = RK[7] ^ RK[14];
639 }
640 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800641#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000642 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800645#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000646}
647
648/*
649 * AES key schedule (decryption)
650 */
Thomas Daubney955ce582024-07-18 11:05:42 +0100651#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100652int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
653 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000654{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800655#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800656 uint32_t *SK;
657#endif
658 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200659 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000660 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800661
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
Gilles Peskine0de8f852023-03-16 17:14:59 +0100665 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100666 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200668 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200670 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000672
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200673 ctx->nr = cty.nr;
674
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100675#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
677 mbedtls_aesni_inverse_key((unsigned char *) RK,
678 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200679 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100680 }
681#endif
682
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800683#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100684 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800685 mbedtls_aesce_inverse_key(
686 (unsigned char *) RK,
687 (const unsigned char *) (cty.buf + cty.rk_offset),
688 ctx->nr);
689 goto exit;
690 }
691#endif
692
Jerry Yu29c91ba2023-08-04 11:02:04 +0800693#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100694 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
696 *RK++ = *SK++;
697 *RK++ = *SK++;
698 *RK++ = *SK++;
699 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800700 SK -= 8;
701 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
702 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
704 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
705 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
706 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000707 }
708 }
709
710 *RK++ = *SK++;
711 *RK++ = *SK++;
712 *RK++ = *SK++;
713 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800714#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200715exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000717
Gilles Peskine449bd832023-01-11 14:50:10 +0100718 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000719}
Thomas Daubney955ce582024-07-18 11:05:42 +0100720#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100721
722#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100723static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
724 unsigned int keybits,
725 const unsigned char **key1,
726 unsigned int *key1bits,
727 const unsigned char **key2,
728 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100729{
730 const unsigned int half_keybits = keybits / 2;
731 const unsigned int half_keybytes = half_keybits / 8;
732
Gilles Peskine449bd832023-01-11 14:50:10 +0100733 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100734 case 256: break;
735 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100737 }
738
739 *key1bits = half_keybits;
740 *key2bits = half_keybits;
741 *key1 = &key[0];
742 *key2 = &key[half_keybytes];
743
744 return 0;
745}
746
Gilles Peskine449bd832023-01-11 14:50:10 +0100747int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
748 const unsigned char *key,
749 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100750{
Janos Follath24eed8d2019-11-22 13:21:35 +0000751 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100752 const unsigned char *key1, *key2;
753 unsigned int key1bits, key2bits;
754
Gilles Peskine449bd832023-01-11 14:50:10 +0100755 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
756 &key2, &key2bits);
757 if (ret != 0) {
758 return ret;
759 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100760
761 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
763 if (ret != 0) {
764 return ret;
765 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100766
767 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100769}
770
Gilles Peskine449bd832023-01-11 14:50:10 +0100771int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
772 const unsigned char *key,
773 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100774{
Janos Follath24eed8d2019-11-22 13:21:35 +0000775 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100776 const unsigned char *key1, *key2;
777 unsigned int key1bits, key2bits;
778
Gilles Peskine449bd832023-01-11 14:50:10 +0100779 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
780 &key2, &key2bits);
781 if (ret != 0) {
782 return ret;
783 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100784
785 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
787 if (ret != 0) {
788 return ret;
789 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100790
791 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100793}
794#endif /* MBEDTLS_CIPHER_MODE_XTS */
795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100797 do \
798 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
800 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
801 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
802 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100803 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
805 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
806 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
807 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100808 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
810 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
811 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
812 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100813 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
815 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
816 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
817 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
818 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100821 do \
822 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100823 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
824 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
825 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
826 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100827 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
829 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
830 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
831 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100832 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
834 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
835 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
836 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100837 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
839 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
840 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
841 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
842 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000843
844/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200845 * AES-ECB block encryption
846 */
Thomas Daubney6cf05f92024-07-18 11:30:22 +0100847MBEDTLS_CHECK_RETURN_TYPICAL
848static int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
849 const unsigned char input[16],
850 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200851{
852 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100853 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100854 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200855 uint32_t X[4];
856 uint32_t Y[4];
857 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200858
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
860 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
861 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
862 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200863
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
865 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]);
866 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 +0200867 }
868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 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 +0200870
Gilles Peskine5197c662020-08-26 17:03:24 +0200871 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
873 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
874 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
875 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200876
Gilles Peskine5197c662020-08-26 17:03:24 +0200877 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
879 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
880 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
881 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200882
Gilles Peskine5197c662020-08-26 17:03:24 +0200883 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
885 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
886 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
887 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200888
Gilles Peskine5197c662020-08-26 17:03:24 +0200889 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
891 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
892 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
893 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200894
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
896 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
897 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
898 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000899
Gilles Peskine449bd832023-01-11 14:50:10 +0100900 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500901
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200903}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200904
Thomas Daubney7c0b4ad2024-07-18 11:58:50 +0100905#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200906/*
907 * AES-ECB block decryption
908 */
Thomas Daubney7c0b4ad2024-07-18 11:58:50 +0100909MBEDTLS_CHECK_RETURN_TYPICAL
910static int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
911 const unsigned char input[16],
912 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200913{
914 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100915 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100916 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200917 uint32_t X[4];
918 uint32_t Y[4];
919 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200920
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
922 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
923 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
924 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200925
Gilles Peskine449bd832023-01-11 14:50:10 +0100926 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
927 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]);
928 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 +0200929 }
930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 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 +0200932
Gilles Peskine5197c662020-08-26 17:03:24 +0200933 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
935 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
936 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
937 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200938
Gilles Peskine5197c662020-08-26 17:03:24 +0200939 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
941 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
942 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
943 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200944
Gilles Peskine5197c662020-08-26 17:03:24 +0200945 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100946 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
947 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
948 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
949 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200950
Gilles Peskine5197c662020-08-26 17:03:24 +0200951 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100952 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
953 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
954 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
955 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200956
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
958 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
959 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
960 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000961
Gilles Peskine449bd832023-01-11 14:50:10 +0100962 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500963
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200965}
Thomas Daubney7c0b4ad2024-07-18 11:58:50 +0100966#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200967
Thomas Daubney62af02c2024-06-14 10:37:13 +0100968/*
Thomas Daubney4e5d1832024-06-25 15:21:48 +0100969 * Our intrinsics-based implementation of AESNI requires the round keys to be
Thomas Daubney62af02c2024-06-14 10:37:13 +0100970 * aligned on a 16-byte boundary. We take care of this before creating them,
971 * but the AES context may have moved (this can happen if the library is
972 * called from a language with managed memory), and in later calls it might
973 * have a different alignment with respect to 16-byte memory. So we may need
974 * to realign.
Gilles Peskine148cad12023-03-16 13:08:42 +0100975 */
Thomas Daubney1d08e2f2024-06-25 09:18:20 +0100976#if defined(MAY_NEED_TO_ALIGN)
Dave Rodgman18ddf612023-10-04 14:03:12 +0100977MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +0100978{
Gilles Peskine0de8f852023-03-16 17:14:59 +0100979 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
980 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +0100981 memmove(ctx->buf + new_offset, // new address
982 ctx->buf + ctx->rk_offset, // current address
983 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
984 ctx->rk_offset = new_offset;
985 }
986}
Thomas Daubney1d08e2f2024-06-25 09:18:20 +0100987#endif /* MAY_NEED_TO_ALIGN */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200988/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000989 * AES-ECB block encryption/decryption
990 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100991int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
992 int mode,
993 const unsigned char input[16],
994 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +0000995{
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +0100997 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100998 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +0100999
Gilles Peskine0de8f852023-03-16 17:14:59 +01001000#if defined(MAY_NEED_TO_ALIGN)
1001 aes_maybe_realign(ctx);
1002#endif
1003
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001004#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1006 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1007 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001008#endif
1009
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001010#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001011 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001012 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1013 }
1014#endif
1015
Jerry Yu29c91ba2023-08-04 11:02:04 +08001016#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001017#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang111159b2023-11-10 13:41:12 +08001018 if (mode == MBEDTLS_AES_DECRYPT) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang111159b2023-11-10 13:41:12 +08001020 } else
Jerry Yu29c91ba2023-08-04 11:02:04 +08001021#endif
Yanray Wang111159b2023-11-10 13:41:12 +08001022 {
1023 return mbedtls_internal_aes_encrypt(ctx, input, output);
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001024 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001025#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001026}
1027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001029
Paul Bakker5121ce52009-01-03 21:22:43 +00001030/*
1031 * AES-CBC buffer encryption/decryption
1032 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001033int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1034 int mode,
1035 size_t length,
1036 unsigned char iv[16],
1037 const unsigned char *input,
1038 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001039{
Gilles Peskine7820a572021-07-07 21:08:28 +02001040 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001041 unsigned char temp[16];
1042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001044 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001046
Paul Elliott2ad93672023-08-11 11:07:06 +01001047 /* Nothing to do if length is zero. */
1048 if (length == 0) {
1049 return 0;
1050 }
1051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 if (length % 16) {
1053 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1054 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001055
Dave Rodgman906c63c2023-06-14 17:53:51 +01001056 const unsigned char *ivp = iv;
1057
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 if (mode == MBEDTLS_AES_DECRYPT) {
1059 while (length > 0) {
1060 memcpy(temp, input, 16);
1061 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1062 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001063 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001065 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001066 * the result for the next block in CBC, and the cost of transferring that data from
1067 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001068 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001071
1072 input += 16;
1073 output += 16;
1074 length -= 16;
1075 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 } else {
1077 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001078 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001079
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1081 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001082 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001083 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001084 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001085
1086 input += 16;
1087 output += 16;
1088 length -= 16;
1089 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001090 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001091 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001092 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001093
Gilles Peskine7820a572021-07-07 21:08:28 +02001094exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001096}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001098
Aorimn5f778012016-06-09 23:22:58 +02001099#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001100
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001101typedef unsigned char mbedtls_be128[16];
1102
1103/*
1104 * GF(2^128) multiplication function
1105 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001106 * This function multiplies a field element by x in the polynomial field
1107 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001108 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001109 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001110 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001111#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001112MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001113#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001114static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001115 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001116{
1117 uint64_t a, b, ra, rb;
1118
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 a = MBEDTLS_GET_UINT64_LE(x, 0);
1120 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001121
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1123 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001124
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1126 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001127}
1128
Aorimn5f778012016-06-09 23:22:58 +02001129/*
1130 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001131 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001132 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001133 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001134 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001135#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001136MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001137#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001138int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1139 int mode,
1140 size_t length,
1141 const unsigned char data_unit[16],
1142 const unsigned char *input,
1143 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001144{
Janos Follath24eed8d2019-11-22 13:21:35 +00001145 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001146 size_t blocks = length / 16;
1147 size_t leftover = length % 16;
1148 unsigned char tweak[16];
1149 unsigned char prev_tweak[16];
1150 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001151
Gilles Peskine449bd832023-01-11 14:50:10 +01001152 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001153 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001155
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001156 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001158 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 }
Aorimn5f778012016-06-09 23:22:58 +02001160
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001161 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001163 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 }
Aorimn5f778012016-06-09 23:22:58 +02001165
Jaeden Amerod82cd862018-04-28 15:02:45 +01001166 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1168 data_unit, tweak);
1169 if (ret != 0) {
1170 return ret;
1171 }
Aorimn5f778012016-06-09 23:22:58 +02001172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001174 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001175 /* We are on the last block in a decrypt operation that has
1176 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001177 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001178 * the leftovers and then update the current tweak for use on this,
1179 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 memcpy(prev_tweak, tweak, sizeof(tweak));
1181 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001182 }
1183
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001185
Gilles Peskine449bd832023-01-11 14:50:10 +01001186 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1187 if (ret != 0) {
1188 return ret;
1189 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001190
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001192
1193 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001194 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001195
1196 output += 16;
1197 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001198 }
1199
Gilles Peskine449bd832023-01-11 14:50:10 +01001200 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001201 /* If we are on the leftover bytes in a decrypt operation, we need to
1202 * use the previous tweak for these bytes (as saved in prev_tweak). */
1203 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001204
Jaeden Amerod82cd862018-04-28 15:02:45 +01001205 /* We are now on the final part of the data unit, which doesn't divide
1206 * evenly by 16. It's time for ciphertext stealing. */
1207 size_t i;
1208 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001209
Jaeden Amerod82cd862018-04-28 15:02:45 +01001210 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001211 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001213 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001214 }
Aorimn5f778012016-06-09 23:22:58 +02001215
Dave Rodgman069e7f42022-11-24 19:37:26 +00001216 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001218
Jaeden Amerod82cd862018-04-28 15:02:45 +01001219 /* Copy ciphertext bytes from the previous block for input in this
1220 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001222
Gilles Peskine449bd832023-01-11 14:50:10 +01001223 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1224 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001225 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 }
Aorimn5f778012016-06-09 23:22:58 +02001227
Jaeden Amerod82cd862018-04-28 15:02:45 +01001228 /* Write the result back to the previous block, overriding the previous
1229 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001230 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001231 }
1232
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001234}
1235#endif /* MBEDTLS_CIPHER_MODE_XTS */
1236
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001237#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001238/*
1239 * AES-CFB128 buffer encryption/decryption
1240 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001241int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1242 int mode,
1243 size_t length,
1244 size_t *iv_off,
1245 unsigned char iv[16],
1246 const unsigned char *input,
1247 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001248{
Paul Bakker27fdf462011-06-09 13:55:13 +00001249 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001250 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001251 size_t n;
1252
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001254 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001256
1257 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001258
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 if (n > 15) {
1260 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1261 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001262
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 if (mode == MBEDTLS_AES_DECRYPT) {
1264 while (length--) {
1265 if (n == 0) {
1266 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1267 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001268 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001270 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001271
1272 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001274 iv[n] = (unsigned char) c;
1275
Gilles Peskine449bd832023-01-11 14:50:10 +01001276 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001277 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 } else {
1279 while (length--) {
1280 if (n == 0) {
1281 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1282 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001283 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001285 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001286
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001288
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001290 }
1291 }
1292
1293 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001294 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001295
Gilles Peskine7820a572021-07-07 21:08:28 +02001296exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001297 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001298}
Paul Bakker556efba2014-01-24 15:38:12 +01001299
1300/*
1301 * AES-CFB8 buffer encryption/decryption
1302 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001303int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1304 int mode,
1305 size_t length,
1306 unsigned char iv[16],
1307 const unsigned char *input,
1308 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001309{
Gilles Peskine7820a572021-07-07 21:08:28 +02001310 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001311 unsigned char c;
1312 unsigned char ov[17];
1313
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001315 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 }
1317 while (length--) {
1318 memcpy(ov, iv, 16);
1319 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1320 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001321 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 }
Paul Bakker556efba2014-01-24 15:38:12 +01001323
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001325 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 }
Paul Bakker556efba2014-01-24 15:38:12 +01001327
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001329
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001331 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 }
Paul Bakker556efba2014-01-24 15:38:12 +01001333
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001335 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001336 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001337
Gilles Peskine7820a572021-07-07 21:08:28 +02001338exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001340}
Simon Butcher76a5b222018-04-22 22:57:27 +01001341#endif /* MBEDTLS_CIPHER_MODE_CFB */
1342
1343#if defined(MBEDTLS_CIPHER_MODE_OFB)
1344/*
1345 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1346 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001347int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1348 size_t length,
1349 size_t *iv_off,
1350 unsigned char iv[16],
1351 const unsigned char *input,
1352 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001353{
Simon Butcherad4e4932018-04-29 00:43:47 +01001354 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001355 size_t n;
1356
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001357 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001358
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 if (n > 15) {
1360 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1361 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001362
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 while (length--) {
1364 if (n == 0) {
1365 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1366 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001367 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001369 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001370 *output++ = *input++ ^ iv[n];
1371
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001373 }
1374
1375 *iv_off = n;
1376
Simon Butcherad4e4932018-04-29 00:43:47 +01001377exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001379}
1380#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001382#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001383/*
1384 * AES-CTR buffer encryption/decryption
1385 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001386int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1387 size_t length,
1388 size_t *nc_off,
1389 unsigned char nonce_counter[16],
1390 unsigned char stream_block[16],
1391 const unsigned char *input,
1392 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001393{
Gilles Peskine7820a572021-07-07 21:08:28 +02001394 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001395
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001396 size_t offset = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001397
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001398 if (offset > 0x0F) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001399 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1400 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001401
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001402 for (size_t i = 0; i < length;) {
1403 size_t n = 16;
1404 if (offset == 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001405 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1406 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001407 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001408 }
Dave Rodgman591ff052024-01-13 16:42:38 +00001409 mbedtls_ctr_increment_counter(nonce_counter);
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001410 } else {
1411 n -= offset;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001412 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001413
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001414 if (n > (length - i)) {
1415 n = (length - i);
1416 }
1417 mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
1418 // offset might be non-zero for the last block, but in that case, we don't use it again
1419 offset = 0;
1420 i += n;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001421 }
1422
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001423 // capture offset for future resumption
1424 *nc_off = (*nc_off + length) % 16;
1425
Gilles Peskine7820a572021-07-07 21:08:28 +02001426 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001427
Gilles Peskine7820a572021-07-07 21:08:28 +02001428exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001430}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001431#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001433#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001434/*
1435 * AES test vectors from:
1436 *
1437 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1438 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001439#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001440static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001441{
1442 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1443 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001444#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001445 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1446 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1447 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1448 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001449#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001450};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001451#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001452
Yanray Wang62c99912023-05-11 11:06:53 +08001453static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001454{
1455 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1456 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001457#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001458 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1459 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1460 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1461 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001462#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001463};
1464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001466static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001467{
1468 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1469 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001470#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001471 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1472 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1473 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1474 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001475#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001476};
1477
Yanray Wang62c99912023-05-11 11:06:53 +08001478static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001479{
1480 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1481 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001482#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001483 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1484 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1485 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1486 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001487#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001488};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001492/*
1493 * AES-CFB128 test vectors from:
1494 *
1495 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1496 */
Yanray Wang62c99912023-05-11 11:06:53 +08001497static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001498{
1499 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1500 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001501#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001502 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1503 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1504 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1505 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1506 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1507 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1508 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001509#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001510};
1511
1512static const unsigned char aes_test_cfb128_iv[16] =
1513{
1514 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1515 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1516};
1517
1518static const unsigned char aes_test_cfb128_pt[64] =
1519{
1520 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1521 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1522 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1523 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1524 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1525 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1526 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1527 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1528};
1529
Yanray Wang62c99912023-05-11 11:06:53 +08001530static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001531{
1532 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1533 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1534 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1535 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1536 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1537 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1538 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1539 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001540#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001541 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1542 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1543 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1544 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1545 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1546 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1547 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1548 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1549 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1550 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1551 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1552 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1553 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1554 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1555 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1556 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001557#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001558};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001559#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001560
Simon Butcherad4e4932018-04-29 00:43:47 +01001561#if defined(MBEDTLS_CIPHER_MODE_OFB)
1562/*
1563 * AES-OFB test vectors from:
1564 *
Simon Butcher5db13622018-06-04 22:11:25 +01001565 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001566 */
Yanray Wang62c99912023-05-11 11:06:53 +08001567static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001568{
1569 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1570 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001571#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001572 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1573 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1574 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1575 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1576 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1577 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1578 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001579#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001580};
1581
1582static const unsigned char aes_test_ofb_iv[16] =
1583{
1584 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1585 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1586};
1587
1588static const unsigned char aes_test_ofb_pt[64] =
1589{
1590 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1591 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1592 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1593 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1594 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1595 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1596 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1597 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1598};
1599
Yanray Wang62c99912023-05-11 11:06:53 +08001600static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001601{
1602 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1603 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1604 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1605 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1606 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1607 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1608 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1609 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001610#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001611 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1612 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1613 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1614 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1615 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1616 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1617 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1618 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1619 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1620 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1621 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1622 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1623 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1624 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1625 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1626 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001627#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001628};
1629#endif /* MBEDTLS_CIPHER_MODE_OFB */
1630
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001631#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001632/*
1633 * AES-CTR test vectors from:
1634 *
1635 * http://www.faqs.org/rfcs/rfc3686.html
1636 */
1637
Yanray Wang62c99912023-05-11 11:06:53 +08001638static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001639{
1640 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1641 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1642 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1643 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1644 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1645 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1646};
1647
Yanray Wang62c99912023-05-11 11:06:53 +08001648static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001649{
1650 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1652 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1653 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1654 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1655 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1656};
1657
Yanray Wang62c99912023-05-11 11:06:53 +08001658static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001659{
1660 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1661 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001662 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1663 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1664 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1665 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1666
1667 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1668 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1669 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1670 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1671 0x20, 0x21, 0x22, 0x23 }
1672};
1673
Yanray Wang62c99912023-05-11 11:06:53 +08001674static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001675{
1676 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1677 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1678 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1679 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1680 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1681 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1682 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1683 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1684 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1685 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1686 0x25, 0xB2, 0x07, 0x2F }
1687};
1688
1689static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001690{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001691#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001692
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001693#if defined(MBEDTLS_CIPHER_MODE_XTS)
1694/*
1695 * AES-XTS test vectors from:
1696 *
1697 * IEEE P1619/D16 Annex B
1698 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1699 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1700 */
1701static const unsigned char aes_test_xts_key[][32] =
1702{
1703 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1707 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1708 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1709 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1710 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1711 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1712 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1713 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1714 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1715};
1716
1717static const unsigned char aes_test_xts_pt32[][32] =
1718{
1719 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1721 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1723 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1724 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1725 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1726 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1727 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1728 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1729 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1730 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1731};
1732
1733static const unsigned char aes_test_xts_ct32[][32] =
1734{
1735 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1736 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1737 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1738 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1739 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1740 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1741 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1742 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1743 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1744 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1745 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1746 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1747};
1748
1749static const unsigned char aes_test_xts_data_unit[][16] =
1750{
Gilles Peskine449bd832023-01-11 14:50:10 +01001751 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1753 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1755 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001757};
1758
1759#endif /* MBEDTLS_CIPHER_MODE_XTS */
1760
Paul Bakker5121ce52009-01-03 21:22:43 +00001761/*
1762 * Checkup routine
1763 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001764int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001765{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001766 int ret = 0, i, j, u, mode;
1767 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001768 unsigned char key[32];
1769 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001770 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001771#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1772 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001773 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001774#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001775#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001776 unsigned char prv[16];
1777#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001778#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1779 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001780 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001781#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001782#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001783 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001784#endif
1785#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001786 unsigned char nonce_counter[16];
1787 unsigned char stream_block[16];
1788#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001789 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001790
Gilles Peskine449bd832023-01-11 14:50:10 +01001791 memset(key, 0, 32);
1792 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001793
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001794 if (verbose != 0) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001795#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001796#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001797 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001798#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001799 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001800#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001801#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001802#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001803 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1804 mbedtls_printf(" AES note: using AESNI.\n");
1805 } else
1806#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001807#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001808 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001809 mbedtls_printf(" AES note: using AESCE.\n");
1810 } else
1811#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001812 {
1813#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1814 mbedtls_printf(" AES note: built-in implementation.\n");
1815#endif
1816 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001817 }
1818
Paul Bakker5121ce52009-01-03 21:22:43 +00001819 /*
1820 * ECB mode
1821 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001822 {
1823 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001824 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001825
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001826 for (i = 0; i < num_tests << 1; i++) {
1827 u = i >> 1;
1828 keybits = 128 + u * 64;
1829 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001830
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001831 if (verbose != 0) {
1832 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1833 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1834 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001835#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001836 if (mode == MBEDTLS_AES_DECRYPT) {
1837 if (verbose != 0) {
1838 mbedtls_printf("skipped\n");
1839 }
1840 continue;
1841 }
1842#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001843
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001844 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001845
Yanray Wangb67b4742023-10-31 17:10:32 +08001846#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001847 if (mode == MBEDTLS_AES_DECRYPT) {
1848 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1849 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001850 } else
1851#endif
1852 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001853 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1854 aes_tests = aes_test_ecb_enc[u];
1855 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001856
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001857 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1858 mbedtls_printf("skipped\n");
1859 continue;
1860 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001861 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001862 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001863
1864 for (j = 0; j < 10000; j++) {
1865 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1866 if (ret != 0) {
1867 goto exit;
1868 }
1869 }
1870
1871 if (memcmp(buf, aes_tests, 16) != 0) {
1872 ret = 1;
1873 goto exit;
1874 }
1875
1876 if (verbose != 0) {
1877 mbedtls_printf("passed\n");
1878 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001879 }
1880
Gilles Peskine449bd832023-01-11 14:50:10 +01001881 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001882 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001883 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001884 }
1885
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001886#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001887 /*
1888 * CBC mode
1889 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001890 {
1891 static const int num_tests =
1892 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001893
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001894 for (i = 0; i < num_tests << 1; i++) {
1895 u = i >> 1;
1896 keybits = 128 + u * 64;
1897 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001898
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001899 if (verbose != 0) {
1900 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1901 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001902 }
1903
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001904 memset(iv, 0, 16);
1905 memset(prv, 0, 16);
1906 memset(buf, 0, 16);
1907
1908 if (mode == MBEDTLS_AES_DECRYPT) {
1909 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1910 aes_tests = aes_test_cbc_dec[u];
1911 } else {
1912 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1913 aes_tests = aes_test_cbc_enc[u];
1914 }
1915
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001916 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1917 mbedtls_printf("skipped\n");
1918 continue;
1919 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001920 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001921 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001922
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001923 for (j = 0; j < 10000; j++) {
1924 if (mode == MBEDTLS_AES_ENCRYPT) {
1925 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001926
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001927 memcpy(tmp, prv, 16);
1928 memcpy(prv, buf, 16);
1929 memcpy(buf, tmp, 16);
1930 }
1931
1932 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1933 if (ret != 0) {
1934 goto exit;
1935 }
1936
1937 }
1938
1939 if (memcmp(buf, aes_tests, 16) != 0) {
1940 ret = 1;
1941 goto exit;
1942 }
1943
1944 if (verbose != 0) {
1945 mbedtls_printf("passed\n");
1946 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001947 }
1948
Gilles Peskine449bd832023-01-11 14:50:10 +01001949 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001950 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001951 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001952 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001953#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001954
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001955#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 /*
1957 * CFB128 mode
1958 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001959 {
1960 static const int num_tests =
1961 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00001962
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001963 for (i = 0; i < num_tests << 1; i++) {
1964 u = i >> 1;
1965 keybits = 128 + u * 64;
1966 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001967
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001968 if (verbose != 0) {
1969 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1970 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1971 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001972
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001973 memcpy(iv, aes_test_cfb128_iv, 16);
1974 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001975
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001976 offset = 0;
1977 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Thomas Daubney742a2e32024-07-18 10:54:33 +01001978
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001979 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1980 mbedtls_printf("skipped\n");
1981 continue;
1982 } else if (ret != 0) {
1983 goto exit;
1984 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001985
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001986 if (mode == MBEDTLS_AES_DECRYPT) {
1987 memcpy(buf, aes_test_cfb128_ct[u], 64);
1988 aes_tests = aes_test_cfb128_pt;
1989 } else {
1990 memcpy(buf, aes_test_cfb128_pt, 64);
1991 aes_tests = aes_test_cfb128_ct[u];
1992 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001993
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001994 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1995 if (ret != 0) {
1996 goto exit;
1997 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001998
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001999 if (memcmp(buf, aes_tests, 64) != 0) {
2000 ret = 1;
2001 goto exit;
2002 }
2003
2004 if (verbose != 0) {
2005 mbedtls_printf("passed\n");
2006 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002007 }
2008
Gilles Peskine449bd832023-01-11 14:50:10 +01002009 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002010 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002011 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002012 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002013#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002014
Simon Butcherad4e4932018-04-29 00:43:47 +01002015#if defined(MBEDTLS_CIPHER_MODE_OFB)
2016 /*
2017 * OFB mode
2018 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002019 {
2020 static const int num_tests =
2021 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002022
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002023 for (i = 0; i < num_tests << 1; i++) {
2024 u = i >> 1;
2025 keybits = 128 + u * 64;
2026 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002027
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002028 if (verbose != 0) {
2029 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2030 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2031 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002032
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002033 memcpy(iv, aes_test_ofb_iv, 16);
2034 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002035
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002036 offset = 0;
2037 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Thomas Daubney742a2e32024-07-18 10:54:33 +01002038
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002039 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2040 mbedtls_printf("skipped\n");
2041 continue;
2042 } else if (ret != 0) {
2043 goto exit;
2044 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002045
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002046 if (mode == MBEDTLS_AES_DECRYPT) {
2047 memcpy(buf, aes_test_ofb_ct[u], 64);
2048 aes_tests = aes_test_ofb_pt;
2049 } else {
2050 memcpy(buf, aes_test_ofb_pt, 64);
2051 aes_tests = aes_test_ofb_ct[u];
2052 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002053
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002054 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2055 if (ret != 0) {
2056 goto exit;
2057 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002058
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002059 if (memcmp(buf, aes_tests, 64) != 0) {
2060 ret = 1;
2061 goto exit;
2062 }
2063
2064 if (verbose != 0) {
2065 mbedtls_printf("passed\n");
2066 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002067 }
2068
Gilles Peskine449bd832023-01-11 14:50:10 +01002069 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002070 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002071 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002072 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002073#endif /* MBEDTLS_CIPHER_MODE_OFB */
2074
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002075#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002076 /*
2077 * CTR mode
2078 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002079 {
2080 static const int num_tests =
2081 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002082
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002083 for (i = 0; i < num_tests << 1; i++) {
2084 u = i >> 1;
2085 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002086
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002087 if (verbose != 0) {
2088 mbedtls_printf(" AES-CTR-128 (%s): ",
2089 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2090 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002091
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002092 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2093 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002094
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002095 offset = 0;
2096 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2097 goto exit;
2098 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002099
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002100 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002101
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002102 if (mode == MBEDTLS_AES_DECRYPT) {
2103 memcpy(buf, aes_test_ctr_ct[u], len);
2104 aes_tests = aes_test_ctr_pt[u];
2105 } else {
2106 memcpy(buf, aes_test_ctr_pt[u], len);
2107 aes_tests = aes_test_ctr_ct[u];
2108 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002109
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002110 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2111 stream_block, buf, buf);
2112 if (ret != 0) {
2113 goto exit;
2114 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002115
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002116 if (memcmp(buf, aes_tests, len) != 0) {
2117 ret = 1;
2118 goto exit;
2119 }
2120
2121 if (verbose != 0) {
2122 mbedtls_printf("passed\n");
2123 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002124 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002125 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002126
Gilles Peskine449bd832023-01-11 14:50:10 +01002127 if (verbose != 0) {
2128 mbedtls_printf("\n");
2129 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002130#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002131
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002132#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002133 /*
2134 * XTS mode
2135 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002136 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002137 static const int num_tests =
2138 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2139 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002140
Gilles Peskine449bd832023-01-11 14:50:10 +01002141 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002142
Gilles Peskine449bd832023-01-11 14:50:10 +01002143 for (i = 0; i < num_tests << 1; i++) {
2144 const unsigned char *data_unit;
2145 u = i >> 1;
2146 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002147
Gilles Peskine449bd832023-01-11 14:50:10 +01002148 if (verbose != 0) {
2149 mbedtls_printf(" AES-XTS-128 (%s): ",
2150 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2151 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002152
Gilles Peskine449bd832023-01-11 14:50:10 +01002153 memset(key, 0, sizeof(key));
2154 memcpy(key, aes_test_xts_key[u], 32);
2155 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002156
Gilles Peskine449bd832023-01-11 14:50:10 +01002157 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002158
Gilles Peskine449bd832023-01-11 14:50:10 +01002159 if (mode == MBEDTLS_AES_DECRYPT) {
2160 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2161 if (ret != 0) {
2162 goto exit;
2163 }
2164 memcpy(buf, aes_test_xts_ct32[u], len);
2165 aes_tests = aes_test_xts_pt32[u];
2166 } else {
2167 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2168 if (ret != 0) {
2169 goto exit;
2170 }
2171 memcpy(buf, aes_test_xts_pt32[u], len);
2172 aes_tests = aes_test_xts_ct32[u];
2173 }
2174
2175
2176 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2177 buf, buf);
2178 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002179 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002180 }
2181
2182 if (memcmp(buf, aes_tests, len) != 0) {
2183 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002184 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002185 }
2186
2187 if (verbose != 0) {
2188 mbedtls_printf("passed\n");
2189 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002190 }
2191
Gilles Peskine449bd832023-01-11 14:50:10 +01002192 if (verbose != 0) {
2193 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002194 }
2195
Gilles Peskine449bd832023-01-11 14:50:10 +01002196 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002197 }
2198#endif /* MBEDTLS_CIPHER_MODE_XTS */
2199
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002200 ret = 0;
2201
2202exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002203 if (ret != 0 && verbose != 0) {
2204 mbedtls_printf("failed\n");
2205 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002206
Gilles Peskine449bd832023-01-11 14:50:10 +01002207 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002208
Gilles Peskine449bd832023-01-11 14:50:10 +01002209 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002210}
2211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002212#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002214#endif /* MBEDTLS_AES_C */