blob: b9145eaff31cdc3da169ca597cb8203bc95e536b [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
Thomas Daubneyd4c886e2024-07-30 10:17:01 +0100844#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Paul Bakker5121ce52009-01-03 21:22:43 +0000845/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200846 * AES-ECB block encryption
847 */
Thomas Daubney6cf05f92024-07-18 11:30:22 +0100848MBEDTLS_CHECK_RETURN_TYPICAL
849static int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
850 const unsigned char input[16],
851 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200852{
853 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100854 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200856 uint32_t X[4];
857 uint32_t Y[4];
858 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200859
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
861 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
862 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
863 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200864
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
866 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]);
867 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 +0200868 }
869
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 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 +0200871
Gilles Peskine5197c662020-08-26 17:03:24 +0200872 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
874 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
875 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
876 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200877
Gilles Peskine5197c662020-08-26 17:03:24 +0200878 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
880 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
881 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
882 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200883
Gilles Peskine5197c662020-08-26 17:03:24 +0200884 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
886 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
887 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
888 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200889
Gilles Peskine5197c662020-08-26 17:03:24 +0200890 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
892 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
893 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
894 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
897 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
898 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
899 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500902
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200904}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200905
Thomas Daubney7c0b4ad2024-07-18 11:58:50 +0100906#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200907/*
908 * AES-ECB block decryption
909 */
Thomas Daubney7c0b4ad2024-07-18 11:58:50 +0100910MBEDTLS_CHECK_RETURN_TYPICAL
911static int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
912 const unsigned char input[16],
913 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200914{
915 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100916 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200918 uint32_t X[4];
919 uint32_t Y[4];
920 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
923 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
924 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
925 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
928 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]);
929 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 +0200930 }
931
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 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 +0200933
Gilles Peskine5197c662020-08-26 17:03:24 +0200934 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
936 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
937 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
938 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200939
Gilles Peskine5197c662020-08-26 17:03:24 +0200940 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
942 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
943 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
944 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200945
Gilles Peskine5197c662020-08-26 17:03:24 +0200946 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
948 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
949 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
950 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200951
Gilles Peskine5197c662020-08-26 17:03:24 +0200952 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
954 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
955 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
956 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
959 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
960 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
961 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000962
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500964
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200966}
Thomas Daubney7c0b4ad2024-07-18 11:58:50 +0100967#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Thomas Daubneyd4c886e2024-07-30 10:17:01 +0100968#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Thomas Daubney62af02c2024-06-14 10:37:13 +0100969/*
Thomas Daubney4e5d1832024-06-25 15:21:48 +0100970 * Our intrinsics-based implementation of AESNI requires the round keys to be
Thomas Daubney62af02c2024-06-14 10:37:13 +0100971 * aligned on a 16-byte boundary. We take care of this before creating them,
972 * but the AES context may have moved (this can happen if the library is
973 * called from a language with managed memory), and in later calls it might
974 * have a different alignment with respect to 16-byte memory. So we may need
975 * to realign.
Gilles Peskine148cad12023-03-16 13:08:42 +0100976 */
Thomas Daubney1d08e2f2024-06-25 09:18:20 +0100977#if defined(MAY_NEED_TO_ALIGN)
Dave Rodgman18ddf612023-10-04 14:03:12 +0100978MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +0100979{
Gilles Peskine0de8f852023-03-16 17:14:59 +0100980 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
981 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +0100982 memmove(ctx->buf + new_offset, // new address
983 ctx->buf + ctx->rk_offset, // current address
984 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
985 ctx->rk_offset = new_offset;
986 }
987}
Thomas Daubney1d08e2f2024-06-25 09:18:20 +0100988#endif /* MAY_NEED_TO_ALIGN */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200989/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000990 * AES-ECB block encryption/decryption
991 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100992int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
993 int mode,
994 const unsigned char input[16],
995 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +0000996{
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +0100998 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001000
Gilles Peskine0de8f852023-03-16 17:14:59 +01001001#if defined(MAY_NEED_TO_ALIGN)
1002 aes_maybe_realign(ctx);
1003#endif
1004
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001005#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1007 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1008 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001009#endif
1010
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001011#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001012 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001013 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1014 }
1015#endif
1016
Jerry Yu29c91ba2023-08-04 11:02:04 +08001017#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001018#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang111159b2023-11-10 13:41:12 +08001019 if (mode == MBEDTLS_AES_DECRYPT) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang111159b2023-11-10 13:41:12 +08001021 } else
Jerry Yu29c91ba2023-08-04 11:02:04 +08001022#endif
Yanray Wang111159b2023-11-10 13:41:12 +08001023 {
1024 return mbedtls_internal_aes_encrypt(ctx, input, output);
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001025 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001026#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001027}
1028
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001029#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001030
Paul Bakker5121ce52009-01-03 21:22:43 +00001031/*
1032 * AES-CBC buffer encryption/decryption
1033 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001034int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1035 int mode,
1036 size_t length,
1037 unsigned char iv[16],
1038 const unsigned char *input,
1039 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001040{
Gilles Peskine7820a572021-07-07 21:08:28 +02001041 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001042 unsigned char temp[16];
1043
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001045 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001047
Paul Elliott2ad93672023-08-11 11:07:06 +01001048 /* Nothing to do if length is zero. */
1049 if (length == 0) {
1050 return 0;
1051 }
1052
Gilles Peskine449bd832023-01-11 14:50:10 +01001053 if (length % 16) {
1054 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1055 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001056
Dave Rodgman906c63c2023-06-14 17:53:51 +01001057 const unsigned char *ivp = iv;
1058
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 if (mode == MBEDTLS_AES_DECRYPT) {
1060 while (length > 0) {
1061 memcpy(temp, input, 16);
1062 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1063 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001064 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001066 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001067 * the result for the next block in CBC, and the cost of transferring that data from
1068 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001069 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001070
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001072
1073 input += 16;
1074 output += 16;
1075 length -= 16;
1076 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 } else {
1078 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001079 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001080
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1082 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001083 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001085 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001086
1087 input += 16;
1088 output += 16;
1089 length -= 16;
1090 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001091 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001092 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001093 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001094
Gilles Peskine7820a572021-07-07 21:08:28 +02001095exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001097}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001099
Aorimn5f778012016-06-09 23:22:58 +02001100#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001101
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001102typedef unsigned char mbedtls_be128[16];
1103
1104/*
1105 * GF(2^128) multiplication function
1106 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001107 * This function multiplies a field element by x in the polynomial field
1108 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001109 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001110 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001111 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001112#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001113MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001114#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001115static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001116 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001117{
1118 uint64_t a, b, ra, rb;
1119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 a = MBEDTLS_GET_UINT64_LE(x, 0);
1121 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001122
Gilles Peskine449bd832023-01-11 14:50:10 +01001123 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1124 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001125
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1127 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001128}
1129
Aorimn5f778012016-06-09 23:22:58 +02001130/*
1131 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001132 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001133 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001134 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001135 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001136#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001137MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001138#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001139int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1140 int mode,
1141 size_t length,
1142 const unsigned char data_unit[16],
1143 const unsigned char *input,
1144 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001145{
Janos Follath24eed8d2019-11-22 13:21:35 +00001146 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001147 size_t blocks = length / 16;
1148 size_t leftover = length % 16;
1149 unsigned char tweak[16];
1150 unsigned char prev_tweak[16];
1151 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001152
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001154 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001156
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001157 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001159 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 }
Aorimn5f778012016-06-09 23:22:58 +02001161
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001162 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001164 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 }
Aorimn5f778012016-06-09 23:22:58 +02001166
Jaeden Amerod82cd862018-04-28 15:02:45 +01001167 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1169 data_unit, tweak);
1170 if (ret != 0) {
1171 return ret;
1172 }
Aorimn5f778012016-06-09 23:22:58 +02001173
Gilles Peskine449bd832023-01-11 14:50:10 +01001174 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001175 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001176 /* We are on the last block in a decrypt operation that has
1177 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001178 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001179 * the leftovers and then update the current tweak for use on this,
1180 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 memcpy(prev_tweak, tweak, sizeof(tweak));
1182 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001183 }
1184
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001186
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1188 if (ret != 0) {
1189 return ret;
1190 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001191
Gilles Peskine449bd832023-01-11 14:50:10 +01001192 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001193
1194 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001195 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001196
1197 output += 16;
1198 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001199 }
1200
Gilles Peskine449bd832023-01-11 14:50:10 +01001201 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001202 /* If we are on the leftover bytes in a decrypt operation, we need to
1203 * use the previous tweak for these bytes (as saved in prev_tweak). */
1204 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001205
Jaeden Amerod82cd862018-04-28 15:02:45 +01001206 /* We are now on the final part of the data unit, which doesn't divide
1207 * evenly by 16. It's time for ciphertext stealing. */
1208 size_t i;
1209 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001210
Jaeden Amerod82cd862018-04-28 15:02:45 +01001211 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001212 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001214 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001215 }
Aorimn5f778012016-06-09 23:22:58 +02001216
Dave Rodgman069e7f42022-11-24 19:37:26 +00001217 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001219
Jaeden Amerod82cd862018-04-28 15:02:45 +01001220 /* Copy ciphertext bytes from the previous block for input in this
1221 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001223
Gilles Peskine449bd832023-01-11 14:50:10 +01001224 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1225 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001226 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 }
Aorimn5f778012016-06-09 23:22:58 +02001228
Jaeden Amerod82cd862018-04-28 15:02:45 +01001229 /* Write the result back to the previous block, overriding the previous
1230 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001232 }
1233
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001235}
1236#endif /* MBEDTLS_CIPHER_MODE_XTS */
1237
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001238#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001239/*
1240 * AES-CFB128 buffer encryption/decryption
1241 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001242int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1243 int mode,
1244 size_t length,
1245 size_t *iv_off,
1246 unsigned char iv[16],
1247 const unsigned char *input,
1248 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001249{
Paul Bakker27fdf462011-06-09 13:55:13 +00001250 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001251 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001252 size_t n;
1253
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001255 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001257
1258 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001259
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 if (n > 15) {
1261 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1262 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001263
Gilles Peskine449bd832023-01-11 14:50:10 +01001264 if (mode == MBEDTLS_AES_DECRYPT) {
1265 while (length--) {
1266 if (n == 0) {
1267 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1268 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001269 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001270 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001271 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001272
1273 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001275 iv[n] = (unsigned char) c;
1276
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001278 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 } else {
1280 while (length--) {
1281 if (n == 0) {
1282 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1283 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001284 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001286 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001287
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001289
Gilles Peskine449bd832023-01-11 14:50:10 +01001290 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001291 }
1292 }
1293
1294 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001295 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001296
Gilles Peskine7820a572021-07-07 21:08:28 +02001297exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001299}
Paul Bakker556efba2014-01-24 15:38:12 +01001300
1301/*
1302 * AES-CFB8 buffer encryption/decryption
1303 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001304int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1305 int mode,
1306 size_t length,
1307 unsigned char iv[16],
1308 const unsigned char *input,
1309 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001310{
Gilles Peskine7820a572021-07-07 21:08:28 +02001311 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001312 unsigned char c;
1313 unsigned char ov[17];
1314
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001316 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 }
1318 while (length--) {
1319 memcpy(ov, iv, 16);
1320 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1321 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001322 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 }
Paul Bakker556efba2014-01-24 15:38:12 +01001324
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001326 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 }
Paul Bakker556efba2014-01-24 15:38:12 +01001328
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001330
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001332 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 }
Paul Bakker556efba2014-01-24 15:38:12 +01001334
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001336 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001337 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001338
Gilles Peskine7820a572021-07-07 21:08:28 +02001339exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001341}
Simon Butcher76a5b222018-04-22 22:57:27 +01001342#endif /* MBEDTLS_CIPHER_MODE_CFB */
1343
1344#if defined(MBEDTLS_CIPHER_MODE_OFB)
1345/*
1346 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1347 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001348int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1349 size_t length,
1350 size_t *iv_off,
1351 unsigned char iv[16],
1352 const unsigned char *input,
1353 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001354{
Simon Butcherad4e4932018-04-29 00:43:47 +01001355 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001356 size_t n;
1357
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001358 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001359
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 if (n > 15) {
1361 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1362 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001363
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 while (length--) {
1365 if (n == 0) {
1366 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1367 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001368 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001369 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001370 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001371 *output++ = *input++ ^ iv[n];
1372
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001374 }
1375
1376 *iv_off = n;
1377
Simon Butcherad4e4932018-04-29 00:43:47 +01001378exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001380}
1381#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001383#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001384/*
1385 * AES-CTR buffer encryption/decryption
1386 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001387int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1388 size_t length,
1389 size_t *nc_off,
1390 unsigned char nonce_counter[16],
1391 unsigned char stream_block[16],
1392 const unsigned char *input,
1393 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001394{
Gilles Peskine7820a572021-07-07 21:08:28 +02001395 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001396
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001397 size_t offset = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001398
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001399 if (offset > 0x0F) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001400 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1401 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001402
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001403 for (size_t i = 0; i < length;) {
1404 size_t n = 16;
1405 if (offset == 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001406 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1407 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001408 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001409 }
Dave Rodgman591ff052024-01-13 16:42:38 +00001410 mbedtls_ctr_increment_counter(nonce_counter);
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001411 } else {
1412 n -= offset;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001413 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001414
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001415 if (n > (length - i)) {
1416 n = (length - i);
1417 }
1418 mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
1419 // offset might be non-zero for the last block, but in that case, we don't use it again
1420 offset = 0;
1421 i += n;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001422 }
1423
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001424 // capture offset for future resumption
1425 *nc_off = (*nc_off + length) % 16;
1426
Gilles Peskine7820a572021-07-07 21:08:28 +02001427 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001428
Gilles Peskine7820a572021-07-07 21:08:28 +02001429exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001430 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001431}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001432#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001434#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001435/*
1436 * AES test vectors from:
1437 *
1438 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1439 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001440#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001441static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001442{
1443 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1444 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001445#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001446 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1447 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1448 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1449 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001450#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001451};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001452#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001453
Yanray Wang62c99912023-05-11 11:06:53 +08001454static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001455{
1456 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1457 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001458#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001459 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1460 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1461 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1462 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001463#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001464};
1465
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001466#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001467static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001468{
1469 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1470 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001471#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001472 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1473 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1474 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1475 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001476#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001477};
1478
Yanray Wang62c99912023-05-11 11:06:53 +08001479static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001480{
1481 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1482 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001483#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001484 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1485 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1486 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1487 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001488#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001489};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001492#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001493/*
1494 * AES-CFB128 test vectors from:
1495 *
1496 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1497 */
Yanray Wang62c99912023-05-11 11:06:53 +08001498static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001499{
1500 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1501 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001502#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001503 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1504 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1505 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1506 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1507 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1508 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1509 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001510#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001511};
1512
1513static const unsigned char aes_test_cfb128_iv[16] =
1514{
1515 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1516 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1517};
1518
1519static const unsigned char aes_test_cfb128_pt[64] =
1520{
1521 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1522 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1523 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1524 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1525 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1526 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1527 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1528 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1529};
1530
Yanray Wang62c99912023-05-11 11:06:53 +08001531static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001532{
1533 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1534 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1535 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1536 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1537 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1538 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1539 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1540 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001541#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001542 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1543 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1544 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1545 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1546 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1547 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1548 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1549 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1550 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1551 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1552 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1553 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1554 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1555 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1556 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1557 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001558#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001559};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001560#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001561
Simon Butcherad4e4932018-04-29 00:43:47 +01001562#if defined(MBEDTLS_CIPHER_MODE_OFB)
1563/*
1564 * AES-OFB test vectors from:
1565 *
Simon Butcher5db13622018-06-04 22:11:25 +01001566 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001567 */
Yanray Wang62c99912023-05-11 11:06:53 +08001568static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001569{
1570 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1571 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001572#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001573 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1574 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1575 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1576 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1577 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1578 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1579 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001580#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001581};
1582
1583static const unsigned char aes_test_ofb_iv[16] =
1584{
1585 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1586 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1587};
1588
1589static const unsigned char aes_test_ofb_pt[64] =
1590{
1591 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1592 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1593 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1594 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1595 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1596 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1597 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1598 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1599};
1600
Yanray Wang62c99912023-05-11 11:06:53 +08001601static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001602{
1603 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1604 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1605 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1606 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1607 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1608 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1609 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1610 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001611#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001612 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1613 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1614 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1615 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1616 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1617 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1618 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1619 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1620 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1621 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1622 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1623 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1624 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1625 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1626 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1627 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001628#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001629};
1630#endif /* MBEDTLS_CIPHER_MODE_OFB */
1631
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001632#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001633/*
1634 * AES-CTR test vectors from:
1635 *
1636 * http://www.faqs.org/rfcs/rfc3686.html
1637 */
1638
Yanray Wang62c99912023-05-11 11:06:53 +08001639static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001640{
1641 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1642 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1643 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1644 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1645 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1646 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1647};
1648
Yanray Wang62c99912023-05-11 11:06:53 +08001649static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001650{
1651 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1653 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1654 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1655 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1656 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1657};
1658
Yanray Wang62c99912023-05-11 11:06:53 +08001659static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001660{
1661 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1662 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001663 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1664 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1665 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1666 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1667
1668 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1669 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1670 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1671 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1672 0x20, 0x21, 0x22, 0x23 }
1673};
1674
Yanray Wang62c99912023-05-11 11:06:53 +08001675static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001676{
1677 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1678 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1679 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1680 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1681 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1682 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1683 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1684 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1685 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1686 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1687 0x25, 0xB2, 0x07, 0x2F }
1688};
1689
1690static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001691{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001692#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001693
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001694#if defined(MBEDTLS_CIPHER_MODE_XTS)
1695/*
1696 * AES-XTS test vectors from:
1697 *
1698 * IEEE P1619/D16 Annex B
1699 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1700 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1701 */
1702static const unsigned char aes_test_xts_key[][32] =
1703{
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1708 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1709 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1710 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1711 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1712 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1713 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1714 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1715 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1716};
1717
1718static const unsigned char aes_test_xts_pt32[][32] =
1719{
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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
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 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1732};
1733
1734static const unsigned char aes_test_xts_ct32[][32] =
1735{
1736 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1737 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1738 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1739 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1740 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1741 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1742 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1743 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1744 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1745 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1746 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1747 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1748};
1749
1750static const unsigned char aes_test_xts_data_unit[][16] =
1751{
Gilles Peskine449bd832023-01-11 14:50:10 +01001752 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1754 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1756 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001758};
1759
1760#endif /* MBEDTLS_CIPHER_MODE_XTS */
1761
Paul Bakker5121ce52009-01-03 21:22:43 +00001762/*
1763 * Checkup routine
1764 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001765int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001766{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001767 int ret = 0, i, j, u, mode;
1768 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001769 unsigned char key[32];
1770 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001771 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001772#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1773 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001774 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001775#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001776#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001777 unsigned char prv[16];
1778#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001779#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1780 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001781 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001782#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001783#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001784 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001785#endif
1786#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001787 unsigned char nonce_counter[16];
1788 unsigned char stream_block[16];
1789#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001790 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001791
Gilles Peskine449bd832023-01-11 14:50:10 +01001792 memset(key, 0, 32);
1793 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001794
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001795 if (verbose != 0) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001796#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001797#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001798 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001799#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001800 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001801#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001802#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001803#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001804 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1805 mbedtls_printf(" AES note: using AESNI.\n");
1806 } else
1807#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001808#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001809 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001810 mbedtls_printf(" AES note: using AESCE.\n");
1811 } else
1812#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001813 {
1814#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1815 mbedtls_printf(" AES note: built-in implementation.\n");
1816#endif
1817 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001818 }
1819
Paul Bakker5121ce52009-01-03 21:22:43 +00001820 /*
1821 * ECB mode
1822 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001823 {
1824 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001825 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001826
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001827 for (i = 0; i < num_tests << 1; i++) {
1828 u = i >> 1;
1829 keybits = 128 + u * 64;
1830 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001831
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001832 if (verbose != 0) {
1833 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1834 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1835 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001836#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001837 if (mode == MBEDTLS_AES_DECRYPT) {
1838 if (verbose != 0) {
1839 mbedtls_printf("skipped\n");
1840 }
1841 continue;
1842 }
1843#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001844
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001845 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001846
Yanray Wangb67b4742023-10-31 17:10:32 +08001847#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001848 if (mode == MBEDTLS_AES_DECRYPT) {
1849 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1850 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001851 } else
1852#endif
1853 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001854 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1855 aes_tests = aes_test_ecb_enc[u];
1856 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001857
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001858 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1859 mbedtls_printf("skipped\n");
1860 continue;
1861 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001862 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001863 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001864
1865 for (j = 0; j < 10000; j++) {
1866 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1867 if (ret != 0) {
1868 goto exit;
1869 }
1870 }
1871
1872 if (memcmp(buf, aes_tests, 16) != 0) {
1873 ret = 1;
1874 goto exit;
1875 }
1876
1877 if (verbose != 0) {
1878 mbedtls_printf("passed\n");
1879 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001880 }
1881
Gilles Peskine449bd832023-01-11 14:50:10 +01001882 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001883 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001884 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001885 }
1886
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001887#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001888 /*
1889 * CBC mode
1890 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001891 {
1892 static const int num_tests =
1893 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001894
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001895 for (i = 0; i < num_tests << 1; i++) {
1896 u = i >> 1;
1897 keybits = 128 + u * 64;
1898 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001899
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001900 if (verbose != 0) {
1901 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1902 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 }
1904
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001905 memset(iv, 0, 16);
1906 memset(prv, 0, 16);
1907 memset(buf, 0, 16);
1908
1909 if (mode == MBEDTLS_AES_DECRYPT) {
1910 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1911 aes_tests = aes_test_cbc_dec[u];
1912 } else {
1913 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1914 aes_tests = aes_test_cbc_enc[u];
1915 }
1916
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001917 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1918 mbedtls_printf("skipped\n");
1919 continue;
1920 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001921 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001922 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001923
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001924 for (j = 0; j < 10000; j++) {
1925 if (mode == MBEDTLS_AES_ENCRYPT) {
1926 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001927
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001928 memcpy(tmp, prv, 16);
1929 memcpy(prv, buf, 16);
1930 memcpy(buf, tmp, 16);
1931 }
1932
1933 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1934 if (ret != 0) {
1935 goto exit;
1936 }
1937
1938 }
1939
1940 if (memcmp(buf, aes_tests, 16) != 0) {
1941 ret = 1;
1942 goto exit;
1943 }
1944
1945 if (verbose != 0) {
1946 mbedtls_printf("passed\n");
1947 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001948 }
1949
Gilles Peskine449bd832023-01-11 14:50:10 +01001950 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001951 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001952 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001953 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001954#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001955
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001956#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001957 /*
1958 * CFB128 mode
1959 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001960 {
1961 static const int num_tests =
1962 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00001963
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001964 for (i = 0; i < num_tests << 1; i++) {
1965 u = i >> 1;
1966 keybits = 128 + u * 64;
1967 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001968
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001969 if (verbose != 0) {
1970 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1971 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1972 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001973
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001974 memcpy(iv, aes_test_cfb128_iv, 16);
1975 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001976
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001977 offset = 0;
1978 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Thomas Daubney742a2e32024-07-18 10:54:33 +01001979
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001980 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1981 mbedtls_printf("skipped\n");
1982 continue;
1983 } else if (ret != 0) {
1984 goto exit;
1985 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001986
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001987 if (mode == MBEDTLS_AES_DECRYPT) {
1988 memcpy(buf, aes_test_cfb128_ct[u], 64);
1989 aes_tests = aes_test_cfb128_pt;
1990 } else {
1991 memcpy(buf, aes_test_cfb128_pt, 64);
1992 aes_tests = aes_test_cfb128_ct[u];
1993 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001994
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001995 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1996 if (ret != 0) {
1997 goto exit;
1998 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001999
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002000 if (memcmp(buf, aes_tests, 64) != 0) {
2001 ret = 1;
2002 goto exit;
2003 }
2004
2005 if (verbose != 0) {
2006 mbedtls_printf("passed\n");
2007 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002008 }
2009
Gilles Peskine449bd832023-01-11 14:50:10 +01002010 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002011 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002012 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002013 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002014#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002015
Simon Butcherad4e4932018-04-29 00:43:47 +01002016#if defined(MBEDTLS_CIPHER_MODE_OFB)
2017 /*
2018 * OFB mode
2019 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002020 {
2021 static const int num_tests =
2022 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002023
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002024 for (i = 0; i < num_tests << 1; i++) {
2025 u = i >> 1;
2026 keybits = 128 + u * 64;
2027 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002028
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002029 if (verbose != 0) {
2030 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2031 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2032 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002033
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002034 memcpy(iv, aes_test_ofb_iv, 16);
2035 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002036
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002037 offset = 0;
2038 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Thomas Daubney742a2e32024-07-18 10:54:33 +01002039
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002040 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2041 mbedtls_printf("skipped\n");
2042 continue;
2043 } else if (ret != 0) {
2044 goto exit;
2045 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002046
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002047 if (mode == MBEDTLS_AES_DECRYPT) {
2048 memcpy(buf, aes_test_ofb_ct[u], 64);
2049 aes_tests = aes_test_ofb_pt;
2050 } else {
2051 memcpy(buf, aes_test_ofb_pt, 64);
2052 aes_tests = aes_test_ofb_ct[u];
2053 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002054
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002055 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2056 if (ret != 0) {
2057 goto exit;
2058 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002059
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002060 if (memcmp(buf, aes_tests, 64) != 0) {
2061 ret = 1;
2062 goto exit;
2063 }
2064
2065 if (verbose != 0) {
2066 mbedtls_printf("passed\n");
2067 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002068 }
2069
Gilles Peskine449bd832023-01-11 14:50:10 +01002070 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002071 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002072 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002073 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002074#endif /* MBEDTLS_CIPHER_MODE_OFB */
2075
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002076#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002077 /*
2078 * CTR mode
2079 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002080 {
2081 static const int num_tests =
2082 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002083
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002084 for (i = 0; i < num_tests << 1; i++) {
2085 u = i >> 1;
2086 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002087
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002088 if (verbose != 0) {
2089 mbedtls_printf(" AES-CTR-128 (%s): ",
2090 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2091 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002092
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002093 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2094 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002095
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 offset = 0;
2097 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2098 goto exit;
2099 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002100
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002101 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002102
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002103 if (mode == MBEDTLS_AES_DECRYPT) {
2104 memcpy(buf, aes_test_ctr_ct[u], len);
2105 aes_tests = aes_test_ctr_pt[u];
2106 } else {
2107 memcpy(buf, aes_test_ctr_pt[u], len);
2108 aes_tests = aes_test_ctr_ct[u];
2109 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002110
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002111 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2112 stream_block, buf, buf);
2113 if (ret != 0) {
2114 goto exit;
2115 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002116
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002117 if (memcmp(buf, aes_tests, len) != 0) {
2118 ret = 1;
2119 goto exit;
2120 }
2121
2122 if (verbose != 0) {
2123 mbedtls_printf("passed\n");
2124 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002125 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002126 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002127
Gilles Peskine449bd832023-01-11 14:50:10 +01002128 if (verbose != 0) {
2129 mbedtls_printf("\n");
2130 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002131#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002132
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002133#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002134 /*
2135 * XTS mode
2136 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002137 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002138 static const int num_tests =
2139 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2140 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002141
Gilles Peskine449bd832023-01-11 14:50:10 +01002142 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002143
Gilles Peskine449bd832023-01-11 14:50:10 +01002144 for (i = 0; i < num_tests << 1; i++) {
2145 const unsigned char *data_unit;
2146 u = i >> 1;
2147 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002148
Gilles Peskine449bd832023-01-11 14:50:10 +01002149 if (verbose != 0) {
2150 mbedtls_printf(" AES-XTS-128 (%s): ",
2151 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2152 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002153
Gilles Peskine449bd832023-01-11 14:50:10 +01002154 memset(key, 0, sizeof(key));
2155 memcpy(key, aes_test_xts_key[u], 32);
2156 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002157
Gilles Peskine449bd832023-01-11 14:50:10 +01002158 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002159
Gilles Peskine449bd832023-01-11 14:50:10 +01002160 if (mode == MBEDTLS_AES_DECRYPT) {
2161 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2162 if (ret != 0) {
2163 goto exit;
2164 }
2165 memcpy(buf, aes_test_xts_ct32[u], len);
2166 aes_tests = aes_test_xts_pt32[u];
2167 } else {
2168 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2169 if (ret != 0) {
2170 goto exit;
2171 }
2172 memcpy(buf, aes_test_xts_pt32[u], len);
2173 aes_tests = aes_test_xts_ct32[u];
2174 }
2175
2176
2177 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2178 buf, buf);
2179 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002180 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002181 }
2182
2183 if (memcmp(buf, aes_tests, len) != 0) {
2184 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002185 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002186 }
2187
2188 if (verbose != 0) {
2189 mbedtls_printf("passed\n");
2190 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002191 }
2192
Gilles Peskine449bd832023-01-11 14:50:10 +01002193 if (verbose != 0) {
2194 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002195 }
2196
Gilles Peskine449bd832023-01-11 14:50:10 +01002197 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002198 }
2199#endif /* MBEDTLS_CIPHER_MODE_XTS */
2200
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002201 ret = 0;
2202
2203exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002204 if (ret != 0 && verbose != 0) {
2205 mbedtls_printf("failed\n");
2206 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002207
Gilles Peskine449bd832023-01-11 14:50:10 +01002208 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002209
Gilles Peskine449bd832023-01-11 14:50:10 +01002210 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002211}
2212
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002213#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002215#endif /* MBEDTLS_AES_C */