blob: b1a5c3ed104827c7f25df8e35a8934b3fb89e77a [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Dave Rodgman16799db2023-11-02 19:47:20 +00005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
Paul Bakker5121ce52009-01-03 21:22:43 +00006 */
7/*
8 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
9 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010010 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
12 */
13
Gilles Peskinedb09ef62020-06-03 01:43:33 +020014#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000015
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020016#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000017
Rich Evans00ab4702015-02-06 13:43:58 +000018#include <string.h>
19
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000020#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030021#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050022#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000023#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080024
Dave Rodgman782df0352023-09-29 12:57:52 +010025#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Dave Rodgman9fd1b522023-10-10 15:23:44 +010026#if !((defined(MBEDTLS_ARCH_IS_ARMV8_A) && defined(MBEDTLS_AESCE_C)) || \
27 (defined(MBEDTLS_ARCH_IS_X64) && defined(MBEDTLS_AESNI_C)) || \
28 (defined(MBEDTLS_ARCH_IS_X86) && defined(MBEDTLS_AESNI_C)))
Jerry Yu69436812023-04-25 11:08:30 +080029#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080030#endif
31#endif
32
Dave Rodgmane81a6322023-09-29 13:54:27 +010033#if defined(MBEDTLS_ARCH_IS_X86)
Jerry Yu61fc5ed2023-08-18 17:28:48 +080034#if defined(MBEDTLS_PADLOCK_C)
35#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080036#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
37#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080038#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
39#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
40 "MBEDTLS_PADLOCK_C is set"
41#endif
42#endif
Jerry Yu02b15192023-04-23 14:43:19 +080043#endif
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000046#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000047#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000049#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010050#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080051#if defined(MBEDTLS_AESCE_C)
52#include "aesce.h"
53#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000054
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000055#include "mbedtls/platform.h"
Dave Rodgman591ff052024-01-13 16:42:38 +000056#include "ctr.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010057
Yanray Wangf03b4912023-11-09 11:23:17 +080058/*
59 * This is a convenience shorthand macro to check if we need reverse S-box and
60 * reverse tables. It's private and only defined in this file.
61 */
62#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \
63 (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \
Yanray Wangb67b4742023-10-31 17:10:32 +080064 !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wangdbcc0c62023-08-30 15:04:01 +080065#define MBEDTLS_AES_NEED_REVERSE_TABLES
66#endif
67
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020069
Jerry Yu9e628622023-08-17 11:20:09 +080070#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000071static int aes_padlock_ace = -1;
72#endif
73
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000075/*
76 * Forward S-box
77 */
Dave Rodgman18ddf612023-10-04 14:03:12 +010078MBEDTLS_MAYBE_UNUSED static const unsigned char FSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +000079{
80 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
81 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
82 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
83 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
84 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
85 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
86 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
87 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
88 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
89 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
90 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
91 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
92 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
93 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
94 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
95 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
96 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
97 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
98 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
99 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
100 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
101 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
102 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
103 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
104 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
105 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
106 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
107 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
108 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
109 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
110 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
111 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
112};
113
114/*
115 * Forward tables
116 */
117#define FT \
118\
Gilles Peskine449bd832023-01-11 14:50:10 +0100119 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
120 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
121 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
122 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
123 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
124 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
125 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
126 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
127 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
128 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
129 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
130 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
131 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
132 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
133 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
134 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
135 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
136 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
137 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
138 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
139 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
140 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
141 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
142 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
143 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
144 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
145 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
146 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
147 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
148 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
149 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
150 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
151 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
152 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
153 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
154 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
155 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
156 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
157 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
158 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
159 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
160 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
161 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
162 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
163 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
164 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
165 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
166 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
167 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
168 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
169 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
170 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
171 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
172 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
173 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
174 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
175 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
176 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
177 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
178 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
179 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
180 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
181 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
182 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 +0000183
Gilles Peskine449bd832023-01-11 14:50:10 +0100184#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100185MBEDTLS_MAYBE_UNUSED static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000186#undef V
187
Gilles Peskine449bd832023-01-11 14:50:10 +0100188#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100189MBEDTLS_MAYBE_UNUSED static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000190#undef V
191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100193MBEDTLS_MAYBE_UNUSED static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000194#undef V
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100197MBEDTLS_MAYBE_UNUSED static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000198#undef V
199
200#undef FT
201
202/*
203 * Reverse S-box
204 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100205MBEDTLS_MAYBE_UNUSED static const unsigned char RSb[256] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000206{
207 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
208 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
209 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
210 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
211 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
212 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
213 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
214 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
215 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
216 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
217 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
218 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
219 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
220 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
221 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
222 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
223 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
224 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
225 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
226 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
227 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
228 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
229 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
230 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
231 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
232 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
233 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
234 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
235 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
236 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
237 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
238 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
239};
240
241/*
242 * Reverse tables
243 */
244#define RT \
245\
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
247 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
248 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
249 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
250 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
251 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
252 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
253 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
254 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
255 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
256 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
257 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
258 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
259 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
260 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
261 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
262 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
263 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
264 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
265 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
266 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
267 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
268 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
269 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
270 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
271 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
272 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
273 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
274 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
275 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
276 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
277 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
278 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
279 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
280 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
281 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
282 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
283 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
284 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
285 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
286 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
287 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
288 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
289 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
290 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
291 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
292 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
293 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
294 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
295 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
296 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
297 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
298 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
299 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
300 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
301 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
302 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
303 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
304 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
305 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
306 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
307 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
308 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
309 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 +0000310
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312#define V(a, b, c, d) 0x##a##b##c##d
Dave Rodgman18ddf612023-10-04 14:03:12 +0100313MBEDTLS_MAYBE_UNUSED static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000314#undef V
315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316#define V(a, b, c, d) 0x##b##c##d##a
Dave Rodgman18ddf612023-10-04 14:03:12 +0100317MBEDTLS_MAYBE_UNUSED static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000318#undef V
319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320#define V(a, b, c, d) 0x##c##d##a##b
Dave Rodgman18ddf612023-10-04 14:03:12 +0100321MBEDTLS_MAYBE_UNUSED static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000322#undef V
323
Gilles Peskine449bd832023-01-11 14:50:10 +0100324#define V(a, b, c, d) 0x##d##a##b##c
Dave Rodgman18ddf612023-10-04 14:03:12 +0100325MBEDTLS_MAYBE_UNUSED static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000326#undef V
327
328#undef RT
329
330/*
331 * Round constants
332 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100333MBEDTLS_MAYBE_UNUSED static const uint32_t round_constants[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000334{
335 0x00000001, 0x00000002, 0x00000004, 0x00000008,
336 0x00000010, 0x00000020, 0x00000040, 0x00000080,
337 0x0000001B, 0x00000036
338};
339
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342/*
343 * Forward S-box & tables
344 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100345MBEDTLS_MAYBE_UNUSED static unsigned char FSb[256];
346MBEDTLS_MAYBE_UNUSED static uint32_t FT0[256];
347MBEDTLS_MAYBE_UNUSED static uint32_t FT1[256];
348MBEDTLS_MAYBE_UNUSED static uint32_t FT2[256];
349MBEDTLS_MAYBE_UNUSED static uint32_t FT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351/*
352 * Reverse S-box & tables
353 */
Dave Rodgman18ddf612023-10-04 14:03:12 +0100354MBEDTLS_MAYBE_UNUSED static unsigned char RSb[256];
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100355
Dave Rodgman18ddf612023-10-04 14:03:12 +0100356MBEDTLS_MAYBE_UNUSED static uint32_t RT0[256];
357MBEDTLS_MAYBE_UNUSED static uint32_t RT1[256];
358MBEDTLS_MAYBE_UNUSED static uint32_t RT2[256];
359MBEDTLS_MAYBE_UNUSED static uint32_t RT3[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
361/*
362 * Round constants
363 */
Dave Rodgman4b779be2023-10-12 16:17:10 +0100364MBEDTLS_MAYBE_UNUSED static uint32_t round_constants[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
366/*
367 * Tables generation code
368 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100369#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
370#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
371#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000372
Dave Rodgman18ddf612023-10-04 14:03:12 +0100373MBEDTLS_MAYBE_UNUSED static int aes_init_done = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
Dave Rodgman18ddf612023-10-04 14:03:12 +0100375MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000376{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800377 int i;
378 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800379 uint8_t pow[256];
380 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
382 /*
383 * compute pow and log tables over GF(2^8)
384 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000386 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800387 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800388 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000389 }
390
391 /*
392 * calculate the round constants
393 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 for (i = 0, x = 1; i < 10; i++) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200395 round_constants[i] = x;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800396 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000397 }
398
399 /*
400 * generate the forward and reverse S-boxes
401 */
402 FSb[0x00] = 0x63;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800403#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000404 RSb[0x63] = 0x00;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800405#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
Gilles Peskine449bd832023-01-11 14:50:10 +0100407 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 x = pow[255 - log[i]];
409
Yanray Wangfe944ce2023-06-26 18:16:01 +0800410 y = x; y = (y << 1) | (y >> 7);
411 x ^= y; y = (y << 1) | (y >> 7);
412 x ^= y; y = (y << 1) | (y >> 7);
413 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 x ^= y ^ 0x63;
415
Yanray Wangfe944ce2023-06-26 18:16:01 +0800416 FSb[i] = x;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800417#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 RSb[x] = (unsigned char) i;
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800419#endif
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 }
421
422 /*
423 * generate the forward and reverse tables
424 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800427 y = XTIME(x);
428 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
Gilles Peskine449bd832023-01-11 14:50:10 +0100430 FT0[i] = ((uint32_t) y) ^
431 ((uint32_t) x << 8) ^
432 ((uint32_t) x << 16) ^
433 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000434
Hanno Beckerad049a92017-06-19 16:31:54 +0100435#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 FT1[i] = ROTL8(FT0[i]);
437 FT2[i] = ROTL8(FT1[i]);
438 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100439#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800441#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 x = RSb[i];
443
Gilles Peskine449bd832023-01-11 14:50:10 +0100444 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
445 ((uint32_t) MUL(0x09, x) << 8) ^
446 ((uint32_t) MUL(0x0D, x) << 16) ^
447 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
Hanno Beckerad049a92017-06-19 16:31:54 +0100449#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100450 RT1[i] = ROTL8(RT0[i]);
451 RT2[i] = ROTL8(RT1[i]);
452 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100453#endif /* !MBEDTLS_AES_FEWER_TABLES */
Yanray Wangdbcc0c62023-08-30 15:04:01 +0800454#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 }
456}
457
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200458#undef ROTL8
459
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Hanno Beckerad049a92017-06-19 16:31:54 +0100462#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200463
Gilles Peskine449bd832023-01-11 14:50:10 +0100464#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
465#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
466#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200467
468#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100469#define AES_RT1(idx) ROTL8(RT0[idx])
470#define AES_RT2(idx) ROTL16(RT0[idx])
471#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200472
473#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100474#define AES_FT1(idx) ROTL8(FT0[idx])
475#define AES_FT2(idx) ROTL16(FT0[idx])
476#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200477
Hanno Becker177d3cf2017-06-07 15:52:48 +0100478#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200479
480#define AES_RT0(idx) RT0[idx]
481#define AES_RT1(idx) RT1[idx]
482#define AES_RT2(idx) RT2[idx]
483#define AES_RT3(idx) RT3[idx]
484
485#define AES_FT0(idx) FT0[idx]
486#define AES_FT1(idx) FT1[idx]
487#define AES_FT2(idx) FT2[idx]
488#define AES_FT3(idx) FT3[idx]
489
Hanno Becker177d3cf2017-06-07 15:52:48 +0100490#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200491
Gilles Peskine449bd832023-01-11 14:50:10 +0100492void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200493{
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200495}
496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200498{
Gilles Peskine449bd832023-01-11 14:50:10 +0100499 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200500 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200502
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200504}
505
Jaeden Amero9366feb2018-05-29 18:55:17 +0100506#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100507void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100508{
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 mbedtls_aes_init(&ctx->crypt);
510 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100511}
512
Gilles Peskine449bd832023-01-11 14:50:10 +0100513void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100514{
Gilles Peskine449bd832023-01-11 14:50:10 +0100515 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100516 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 }
Simon Butcher5201e412018-12-06 17:40:14 +0000518
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 mbedtls_aes_free(&ctx->crypt);
520 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100521}
522#endif /* MBEDTLS_CIPHER_MODE_XTS */
523
Gilles Peskine0de8f852023-03-16 17:14:59 +0100524/* Some implementations need the round keys to be aligned.
525 * Return an offset to be added to buf, such that (buf + offset) is
526 * correctly aligned.
527 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
528 * i.e. an offset of 1 means 4 bytes and so on.
529 */
Jerry Yu96084472023-08-17 18:10:45 +0800530#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100531 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100532#define MAY_NEED_TO_ALIGN
533#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100534
Dave Rodgman18ddf612023-10-04 14:03:12 +0100535MBEDTLS_MAYBE_UNUSED static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100536{
537#if defined(MAY_NEED_TO_ALIGN)
538 int align_16_bytes = 0;
539
Jerry Yu9e628622023-08-17 11:20:09 +0800540#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100541 if (aes_padlock_ace == -1) {
542 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
543 }
544 if (aes_padlock_ace) {
545 align_16_bytes = 1;
546 }
547#endif
548
Gilles Peskine9c682e72023-03-16 17:21:33 +0100549#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100550 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
551 align_16_bytes = 1;
552 }
553#endif
554
555 if (align_16_bytes) {
556 /* These implementations needs 16-byte alignment
557 * for the round key array. */
558 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
559 if (delta == 0) {
560 return 0;
561 } else {
562 return 4 - delta; // 16 bytes = 4 uint32_t
563 }
564 }
565#else /* MAY_NEED_TO_ALIGN */
566 (void) buf;
567#endif /* MAY_NEED_TO_ALIGN */
568
569 return 0;
570}
571
Paul Bakker5121ce52009-01-03 21:22:43 +0000572/*
573 * AES key schedule (encryption)
574 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200575#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100576int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
577 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000578{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000579 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
Gilles Peskine449bd832023-01-11 14:50:10 +0100581 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800583#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 case 192: ctx->nr = 12; break;
585 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800586#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100587 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000588 }
589
Simon Butcher5201e412018-12-06 17:40:14 +0000590#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000592 aes_gen_tables();
593 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000594 }
595#endif
596
Gilles Peskine0de8f852023-03-16 17:14:59 +0100597 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100598 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100600#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
602 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
603 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100604#endif
605
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800606#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100607 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800608 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
609 }
610#endif
611
Jerry Yu29c91ba2023-08-04 11:02:04 +0800612#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800613 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000615 }
616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000618 case 10:
619
Jerry Yu3a0f0442023-08-17 17:06:21 +0800620 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200621 RK[4] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
623 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
624 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
625 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
627 RK[5] = RK[1] ^ RK[4];
628 RK[6] = RK[2] ^ RK[5];
629 RK[7] = RK[3] ^ RK[6];
630 }
631 break;
632
Arto Kinnunen732ca322023-04-14 14:26:10 +0800633#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 case 12:
635
Jerry Yu3a0f0442023-08-17 17:06:21 +0800636 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200637 RK[6] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
639 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
640 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
641 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000642
643 RK[7] = RK[1] ^ RK[6];
644 RK[8] = RK[2] ^ RK[7];
645 RK[9] = RK[3] ^ RK[8];
646 RK[10] = RK[4] ^ RK[9];
647 RK[11] = RK[5] ^ RK[10];
648 }
649 break;
650
651 case 14:
652
Jerry Yu3a0f0442023-08-17 17:06:21 +0800653 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Jerzy Kasenbergee62fce2023-10-11 16:36:24 +0200654 RK[8] = RK[0] ^ round_constants[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
656 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
657 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
658 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000659
660 RK[9] = RK[1] ^ RK[8];
661 RK[10] = RK[2] ^ RK[9];
662 RK[11] = RK[3] ^ RK[10];
663
664 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
666 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
667 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
668 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000669
670 RK[13] = RK[5] ^ RK[12];
671 RK[14] = RK[6] ^ RK[13];
672 RK[15] = RK[7] ^ RK[14];
673 }
674 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800675#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000676 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000677
Gilles Peskine449bd832023-01-11 14:50:10 +0100678 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800679#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000680}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200681#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000682
683/*
684 * AES key schedule (decryption)
685 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800686#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100687int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
688 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000689{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800690#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800691 uint32_t *SK;
692#endif
693 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000695 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800696
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000699
Gilles Peskine0de8f852023-03-16 17:14:59 +0100700 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100701 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000702
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200703 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200705 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000707
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200708 ctx->nr = cty.nr;
709
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100710#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
712 mbedtls_aesni_inverse_key((unsigned char *) RK,
713 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200714 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100715 }
716#endif
717
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800718#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100719 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800720 mbedtls_aesce_inverse_key(
721 (unsigned char *) RK,
722 (const unsigned char *) (cty.buf + cty.rk_offset),
723 ctx->nr);
724 goto exit;
725 }
726#endif
727
Jerry Yu29c91ba2023-08-04 11:02:04 +0800728#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100729 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
731 *RK++ = *SK++;
732 *RK++ = *SK++;
733 *RK++ = *SK++;
734 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800735 SK -= 8;
736 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
737 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100738 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
739 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
740 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
741 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000742 }
743 }
744
745 *RK++ = *SK++;
746 *RK++ = *SK++;
747 *RK++ = *SK++;
748 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800749#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200750exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000754}
Yanray Wangb67b4742023-10-31 17:10:32 +0800755#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100756
757#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100758static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
759 unsigned int keybits,
760 const unsigned char **key1,
761 unsigned int *key1bits,
762 const unsigned char **key2,
763 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100764{
765 const unsigned int half_keybits = keybits / 2;
766 const unsigned int half_keybytes = half_keybits / 8;
767
Gilles Peskine449bd832023-01-11 14:50:10 +0100768 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100769 case 256: break;
770 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100772 }
773
774 *key1bits = half_keybits;
775 *key2bits = half_keybits;
776 *key1 = &key[0];
777 *key2 = &key[half_keybytes];
778
779 return 0;
780}
781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
783 const unsigned char *key,
784 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100785{
Janos Follath24eed8d2019-11-22 13:21:35 +0000786 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100787 const unsigned char *key1, *key2;
788 unsigned int key1bits, key2bits;
789
Gilles Peskine449bd832023-01-11 14:50:10 +0100790 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
791 &key2, &key2bits);
792 if (ret != 0) {
793 return ret;
794 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100795
796 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
798 if (ret != 0) {
799 return ret;
800 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100801
802 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100804}
805
Gilles Peskine449bd832023-01-11 14:50:10 +0100806int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
807 const unsigned char *key,
808 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100809{
Janos Follath24eed8d2019-11-22 13:21:35 +0000810 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100811 const unsigned char *key1, *key2;
812 unsigned int key1bits, key2bits;
813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
815 &key2, &key2bits);
816 if (ret != 0) {
817 return ret;
818 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100819
820 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
822 if (ret != 0) {
823 return ret;
824 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100825
826 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100828}
829#endif /* MBEDTLS_CIPHER_MODE_XTS */
830
Gilles Peskine449bd832023-01-11 14:50:10 +0100831#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100832 do \
833 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
835 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
836 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
837 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100838 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
840 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
841 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
842 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100843 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100844 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
845 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
846 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
847 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100848 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
850 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
851 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
852 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
853 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100856 do \
857 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
859 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
860 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
861 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100862 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
864 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
865 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
866 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100867 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
869 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
870 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
871 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100872 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
874 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
875 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
876 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
877 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000878
879/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200880 * AES-ECB block encryption
881 */
882#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100883int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
884 const unsigned char input[16],
885 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200886{
887 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100888 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200890 uint32_t X[4];
891 uint32_t Y[4];
892 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200893
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
895 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
896 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
897 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200898
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
900 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]);
901 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 +0200902 }
903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 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 +0200905
Gilles Peskine5197c662020-08-26 17:03:24 +0200906 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
908 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
909 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
910 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200911
Gilles Peskine5197c662020-08-26 17:03:24 +0200912 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
914 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
915 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
916 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200917
Gilles Peskine5197c662020-08-26 17:03:24 +0200918 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
920 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
921 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
922 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200923
Gilles Peskine5197c662020-08-26 17:03:24 +0200924 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
926 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
927 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
928 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
931 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
932 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
933 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200938}
939#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
940
941/*
942 * AES-ECB block decryption
943 */
Yanray Wangb67b4742023-10-31 17:10:32 +0800944#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100945int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
946 const unsigned char input[16],
947 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200948{
949 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100950 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200952 uint32_t X[4];
953 uint32_t Y[4];
954 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
957 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
958 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
959 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200960
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
962 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]);
963 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 +0200964 }
965
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 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 +0200967
Gilles Peskine5197c662020-08-26 17:03:24 +0200968 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100969 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
970 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
971 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
972 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200973
Gilles Peskine5197c662020-08-26 17:03:24 +0200974 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
976 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
977 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
978 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200979
Gilles Peskine5197c662020-08-26 17:03:24 +0200980 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
982 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
983 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200985
Gilles Peskine5197c662020-08-26 17:03:24 +0200986 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
988 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
989 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200991
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
993 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
994 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
995 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500998
Gilles Peskine449bd832023-01-11 14:50:10 +0100999 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001000}
Yanray Wangb67b4742023-10-31 17:10:32 +08001001#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001002
Gilles Peskine148cad12023-03-16 13:08:42 +01001003/* VIA Padlock and our intrinsics-based implementation of AESNI require
1004 * the round keys to be aligned on a 16-byte boundary. We take care of this
1005 * before creating them, but the AES context may have moved (this can happen
1006 * if the library is called from a language with managed memory), and in later
1007 * calls it might have a different alignment with respect to 16-byte memory.
1008 * So we may need to realign.
1009 */
Dave Rodgman18ddf612023-10-04 14:03:12 +01001010MBEDTLS_MAYBE_UNUSED static void aes_maybe_realign(mbedtls_aes_context *ctx)
Gilles Peskine148cad12023-03-16 13:08:42 +01001011{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001012 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1013 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001014 memmove(ctx->buf + new_offset, // new address
1015 ctx->buf + ctx->rk_offset, // current address
1016 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1017 ctx->rk_offset = new_offset;
1018 }
1019}
Gilles Peskine148cad12023-03-16 13:08:42 +01001020
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001021/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 * AES-ECB block encryption/decryption
1023 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001024int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1025 int mode,
1026 const unsigned char input[16],
1027 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001028{
Gilles Peskine449bd832023-01-11 14:50:10 +01001029 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001030 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001032
Gilles Peskine0de8f852023-03-16 17:14:59 +01001033#if defined(MAY_NEED_TO_ALIGN)
1034 aes_maybe_realign(ctx);
1035#endif
1036
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001037#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1039 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1040 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001041#endif
1042
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001043#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001044 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001045 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1046 }
1047#endif
1048
Jerry Yu9e628622023-08-17 11:20:09 +08001049#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001051 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001052 }
1053#endif
1054
Jerry Yu29c91ba2023-08-04 11:02:04 +08001055#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001056#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang111159b2023-11-10 13:41:12 +08001057 if (mode == MBEDTLS_AES_DECRYPT) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001058 return mbedtls_internal_aes_decrypt(ctx, input, output);
Yanray Wang111159b2023-11-10 13:41:12 +08001059 } else
Jerry Yu29c91ba2023-08-04 11:02:04 +08001060#endif
Yanray Wang111159b2023-11-10 13:41:12 +08001061 {
1062 return mbedtls_internal_aes_encrypt(ctx, input, output);
Yanray Wang0d76b6e2023-11-02 11:54:39 +08001063 }
Yanray Wang78ee0c92023-05-15 11:23:50 +08001064#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +00001065}
1066
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001068
Paul Bakker5121ce52009-01-03 21:22:43 +00001069/*
1070 * AES-CBC buffer encryption/decryption
1071 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001072int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1073 int mode,
1074 size_t length,
1075 unsigned char iv[16],
1076 const unsigned char *input,
1077 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001078{
Gilles Peskine7820a572021-07-07 21:08:28 +02001079 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001080 unsigned char temp[16];
1081
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001083 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001085
Paul Elliott2ad93672023-08-11 11:07:06 +01001086 /* Nothing to do if length is zero. */
1087 if (length == 0) {
1088 return 0;
1089 }
1090
Gilles Peskine449bd832023-01-11 14:50:10 +01001091 if (length % 16) {
1092 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1093 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001094
Jerry Yu9e628622023-08-17 11:20:09 +08001095#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001096 if (aes_padlock_ace > 0) {
1097 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1098 return 0;
1099 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001100
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001101 // If padlock data misaligned, we just fall back to
1102 // unaccelerated mode
1103 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001104 }
1105#endif
1106
Dave Rodgman906c63c2023-06-14 17:53:51 +01001107 const unsigned char *ivp = iv;
1108
Gilles Peskine449bd832023-01-11 14:50:10 +01001109 if (mode == MBEDTLS_AES_DECRYPT) {
1110 while (length > 0) {
1111 memcpy(temp, input, 16);
1112 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1113 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001114 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001116 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001117 * the result for the next block in CBC, and the cost of transferring that data from
1118 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001119 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001120
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001122
1123 input += 16;
1124 output += 16;
1125 length -= 16;
1126 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 } else {
1128 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001129 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001130
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1132 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001133 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001135 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001136
1137 input += 16;
1138 output += 16;
1139 length -= 16;
1140 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001141 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001142 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001143 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001144
Gilles Peskine7820a572021-07-07 21:08:28 +02001145exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001147}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001148#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001149
Aorimn5f778012016-06-09 23:22:58 +02001150#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001151
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001152typedef unsigned char mbedtls_be128[16];
1153
1154/*
1155 * GF(2^128) multiplication function
1156 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001157 * This function multiplies a field element by x in the polynomial field
1158 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001159 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001160 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001161 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001162#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001163MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001164#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001165static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001166 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001167{
1168 uint64_t a, b, ra, rb;
1169
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 a = MBEDTLS_GET_UINT64_LE(x, 0);
1171 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1174 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1177 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001178}
1179
Aorimn5f778012016-06-09 23:22:58 +02001180/*
1181 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001182 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001183 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001184 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001185 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001186#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001187MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001188#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001189int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1190 int mode,
1191 size_t length,
1192 const unsigned char data_unit[16],
1193 const unsigned char *input,
1194 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001195{
Janos Follath24eed8d2019-11-22 13:21:35 +00001196 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001197 size_t blocks = length / 16;
1198 size_t leftover = length % 16;
1199 unsigned char tweak[16];
1200 unsigned char prev_tweak[16];
1201 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001202
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001204 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001205 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001206
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001207 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001209 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001210 }
Aorimn5f778012016-06-09 23:22:58 +02001211
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001212 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001214 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 }
Aorimn5f778012016-06-09 23:22:58 +02001216
Jaeden Amerod82cd862018-04-28 15:02:45 +01001217 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1219 data_unit, tweak);
1220 if (ret != 0) {
1221 return ret;
1222 }
Aorimn5f778012016-06-09 23:22:58 +02001223
Gilles Peskine449bd832023-01-11 14:50:10 +01001224 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001225 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001226 /* We are on the last block in a decrypt operation that has
1227 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001228 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001229 * the leftovers and then update the current tweak for use on this,
1230 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 memcpy(prev_tweak, tweak, sizeof(tweak));
1232 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001233 }
1234
Gilles Peskine449bd832023-01-11 14:50:10 +01001235 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001236
Gilles Peskine449bd832023-01-11 14:50:10 +01001237 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1238 if (ret != 0) {
1239 return ret;
1240 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001241
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001243
1244 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001246
1247 output += 16;
1248 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001249 }
1250
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252 /* If we are on the leftover bytes in a decrypt operation, we need to
1253 * use the previous tweak for these bytes (as saved in prev_tweak). */
1254 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001255
Jaeden Amerod82cd862018-04-28 15:02:45 +01001256 /* We are now on the final part of the data unit, which doesn't divide
1257 * evenly by 16. It's time for ciphertext stealing. */
1258 size_t i;
1259 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001260
Jaeden Amerod82cd862018-04-28 15:02:45 +01001261 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001262 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001264 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001265 }
Aorimn5f778012016-06-09 23:22:58 +02001266
Dave Rodgman069e7f42022-11-24 19:37:26 +00001267 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001269
Jaeden Amerod82cd862018-04-28 15:02:45 +01001270 /* Copy ciphertext bytes from the previous block for input in this
1271 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001273
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1275 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001276 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 }
Aorimn5f778012016-06-09 23:22:58 +02001278
Jaeden Amerod82cd862018-04-28 15:02:45 +01001279 /* Write the result back to the previous block, overriding the previous
1280 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001282 }
1283
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001285}
1286#endif /* MBEDTLS_CIPHER_MODE_XTS */
1287
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001288#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001289/*
1290 * AES-CFB128 buffer encryption/decryption
1291 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001292int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1293 int mode,
1294 size_t length,
1295 size_t *iv_off,
1296 unsigned char iv[16],
1297 const unsigned char *input,
1298 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001299{
Paul Bakker27fdf462011-06-09 13:55:13 +00001300 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001301 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001302 size_t n;
1303
Gilles Peskine449bd832023-01-11 14:50:10 +01001304 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001305 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001306 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001307
1308 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001309
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 if (n > 15) {
1311 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1312 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001313
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 if (mode == MBEDTLS_AES_DECRYPT) {
1315 while (length--) {
1316 if (n == 0) {
1317 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1318 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001319 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001321 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001322
1323 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001325 iv[n] = (unsigned char) c;
1326
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001328 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 } else {
1330 while (length--) {
1331 if (n == 0) {
1332 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1333 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001334 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001336 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001337
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001339
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001341 }
1342 }
1343
1344 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001345 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001346
Gilles Peskine7820a572021-07-07 21:08:28 +02001347exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001348 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001349}
Paul Bakker556efba2014-01-24 15:38:12 +01001350
1351/*
1352 * AES-CFB8 buffer encryption/decryption
1353 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001354int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1355 int mode,
1356 size_t length,
1357 unsigned char iv[16],
1358 const unsigned char *input,
1359 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001360{
Gilles Peskine7820a572021-07-07 21:08:28 +02001361 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001362 unsigned char c;
1363 unsigned char ov[17];
1364
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001366 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001367 }
1368 while (length--) {
1369 memcpy(ov, iv, 16);
1370 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1371 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001372 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 }
Paul Bakker556efba2014-01-24 15:38:12 +01001374
Gilles Peskine449bd832023-01-11 14:50:10 +01001375 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001376 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 }
Paul Bakker556efba2014-01-24 15:38:12 +01001378
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001380
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001382 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 }
Paul Bakker556efba2014-01-24 15:38:12 +01001384
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001386 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001387 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001388
Gilles Peskine7820a572021-07-07 21:08:28 +02001389exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001390 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001391}
Simon Butcher76a5b222018-04-22 22:57:27 +01001392#endif /* MBEDTLS_CIPHER_MODE_CFB */
1393
1394#if defined(MBEDTLS_CIPHER_MODE_OFB)
1395/*
1396 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1397 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001398int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1399 size_t length,
1400 size_t *iv_off,
1401 unsigned char iv[16],
1402 const unsigned char *input,
1403 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001404{
Simon Butcherad4e4932018-04-29 00:43:47 +01001405 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001406 size_t n;
1407
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001408 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001409
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 if (n > 15) {
1411 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1412 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001413
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 while (length--) {
1415 if (n == 0) {
1416 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1417 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001418 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001420 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001421 *output++ = *input++ ^ iv[n];
1422
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001424 }
1425
1426 *iv_off = n;
1427
Simon Butcherad4e4932018-04-29 00:43:47 +01001428exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001429 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001430}
1431#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001433#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001434/*
1435 * AES-CTR buffer encryption/decryption
1436 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001437int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1438 size_t length,
1439 size_t *nc_off,
1440 unsigned char nonce_counter[16],
1441 unsigned char stream_block[16],
1442 const unsigned char *input,
1443 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001444{
Gilles Peskine7820a572021-07-07 21:08:28 +02001445 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001446
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001447 size_t offset = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001448
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001449 if (offset > 0x0F) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001450 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1451 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001452
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001453 for (size_t i = 0; i < length;) {
1454 size_t n = 16;
1455 if (offset == 0) {
Gilles Peskine449bd832023-01-11 14:50:10 +01001456 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1457 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001458 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 }
Dave Rodgman591ff052024-01-13 16:42:38 +00001460 mbedtls_ctr_increment_counter(nonce_counter);
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001461 } else {
1462 n -= offset;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001463 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001464
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001465 if (n > (length - i)) {
1466 n = (length - i);
1467 }
1468 mbedtls_xor(&output[i], &input[i], &stream_block[offset], n);
1469 // offset might be non-zero for the last block, but in that case, we don't use it again
1470 offset = 0;
1471 i += n;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001472 }
1473
Dave Rodgmanc4f984f2024-01-12 18:29:01 +00001474 // capture offset for future resumption
1475 *nc_off = (*nc_off + length) % 16;
1476
Gilles Peskine7820a572021-07-07 21:08:28 +02001477 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001478
Gilles Peskine7820a572021-07-07 21:08:28 +02001479exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001480 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001481}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001485
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001487/*
1488 * AES test vectors from:
1489 *
1490 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1491 */
Yanray Wangb67b4742023-10-31 17:10:32 +08001492#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang62c99912023-05-11 11:06:53 +08001493static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001494{
1495 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1496 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001497#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001498 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1499 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1500 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1501 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001502#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001503};
Yanray Wang78ee0c92023-05-15 11:23:50 +08001504#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001505
Yanray Wang62c99912023-05-11 11:06:53 +08001506static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001507{
1508 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1509 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001510#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001511 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1512 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1513 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1514 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001515#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001516};
1517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001519static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001520{
1521 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1522 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001523#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001524 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1525 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1526 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1527 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001528#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001529};
1530
Yanray Wang62c99912023-05-11 11:06:53 +08001531static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001532{
1533 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1534 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001535#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001536 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1537 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1538 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1539 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001540#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001541};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001544#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001545/*
1546 * AES-CFB128 test vectors from:
1547 *
1548 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1549 */
Yanray Wang62c99912023-05-11 11:06:53 +08001550static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001551{
1552 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1553 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001554#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001555 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1556 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1557 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1558 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1559 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1560 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1561 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001562#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001563};
1564
1565static const unsigned char aes_test_cfb128_iv[16] =
1566{
1567 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1568 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1569};
1570
1571static const unsigned char aes_test_cfb128_pt[64] =
1572{
1573 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1574 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1575 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1576 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1577 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1578 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1579 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1580 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1581};
1582
Yanray Wang62c99912023-05-11 11:06:53 +08001583static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001584{
1585 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1586 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1587 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1588 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1589 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1590 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1591 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1592 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001593#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001594 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1595 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1596 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1597 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1598 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1599 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1600 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1601 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1602 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1603 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1604 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1605 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1606 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1607 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1608 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1609 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001610#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001611};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001612#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001613
Simon Butcherad4e4932018-04-29 00:43:47 +01001614#if defined(MBEDTLS_CIPHER_MODE_OFB)
1615/*
1616 * AES-OFB test vectors from:
1617 *
Simon Butcher5db13622018-06-04 22:11:25 +01001618 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001619 */
Yanray Wang62c99912023-05-11 11:06:53 +08001620static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001621{
1622 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1623 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001624#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001625 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1626 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1627 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1628 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1629 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1630 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1631 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001632#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001633};
1634
1635static const unsigned char aes_test_ofb_iv[16] =
1636{
1637 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1638 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1639};
1640
1641static const unsigned char aes_test_ofb_pt[64] =
1642{
1643 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1644 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1645 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1646 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1647 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1648 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1649 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1650 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1651};
1652
Yanray Wang62c99912023-05-11 11:06:53 +08001653static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001654{
1655 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1656 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1657 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1658 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1659 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1660 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1661 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1662 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001663#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001664 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1665 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1666 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1667 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1668 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1669 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1670 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1671 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1672 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1673 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1674 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1675 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1676 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1677 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1678 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1679 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001680#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001681};
1682#endif /* MBEDTLS_CIPHER_MODE_OFB */
1683
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001684#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001685/*
1686 * AES-CTR test vectors from:
1687 *
1688 * http://www.faqs.org/rfcs/rfc3686.html
1689 */
1690
Yanray Wang62c99912023-05-11 11:06:53 +08001691static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001692{
1693 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1694 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1695 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1696 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1697 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1698 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1699};
1700
Yanray Wang62c99912023-05-11 11:06:53 +08001701static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001702{
1703 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1705 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1706 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1707 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1708 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1709};
1710
Yanray Wang62c99912023-05-11 11:06:53 +08001711static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001712{
1713 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1714 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001715 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1716 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1717 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1718 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1719
1720 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1721 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1722 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1723 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1724 0x20, 0x21, 0x22, 0x23 }
1725};
1726
Yanray Wang62c99912023-05-11 11:06:53 +08001727static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001728{
1729 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1730 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1731 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1732 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1733 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1734 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1735 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1736 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1737 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1738 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1739 0x25, 0xB2, 0x07, 0x2F }
1740};
1741
1742static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001743{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001744#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001745
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001746#if defined(MBEDTLS_CIPHER_MODE_XTS)
1747/*
1748 * AES-XTS test vectors from:
1749 *
1750 * IEEE P1619/D16 Annex B
1751 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1752 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1753 */
1754static const unsigned char aes_test_xts_key[][32] =
1755{
1756 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1760 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1761 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1762 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1763 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1764 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1765 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1766 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1767 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1768};
1769
1770static const unsigned char aes_test_xts_pt32[][32] =
1771{
1772 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1776 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1777 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1778 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1779 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1780 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1781 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1782 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1783 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1784};
1785
1786static const unsigned char aes_test_xts_ct32[][32] =
1787{
1788 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1789 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1790 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1791 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1792 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1793 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1794 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1795 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1796 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1797 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1798 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1799 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1800};
1801
1802static const unsigned char aes_test_xts_data_unit[][16] =
1803{
Gilles Peskine449bd832023-01-11 14:50:10 +01001804 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1805 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1806 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1808 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001810};
1811
1812#endif /* MBEDTLS_CIPHER_MODE_XTS */
1813
Paul Bakker5121ce52009-01-03 21:22:43 +00001814/*
1815 * Checkup routine
1816 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001817int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001818{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001819 int ret = 0, i, j, u, mode;
1820 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001821 unsigned char key[32];
1822 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001823 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001824#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1825 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001826 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001827#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001829 unsigned char prv[16];
1830#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001831#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1832 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001833 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001834#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001835#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001836 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001837#endif
1838#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001839 unsigned char nonce_counter[16];
1840 unsigned char stream_block[16];
1841#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001842 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001843
Gilles Peskine449bd832023-01-11 14:50:10 +01001844 memset(key, 0, 32);
1845 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001846
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001847 if (verbose != 0) {
1848#if defined(MBEDTLS_AES_ALT)
1849 mbedtls_printf(" AES note: alternative implementation.\n");
1850#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001851#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001852#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001853 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001854#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001855 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001856#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001857#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001858#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001859 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1860 mbedtls_printf(" AES note: using AESNI.\n");
1861 } else
1862#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001863#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001864 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1865 mbedtls_printf(" AES note: using VIA Padlock.\n");
1866 } else
1867#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001868#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001869 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001870 mbedtls_printf(" AES note: using AESCE.\n");
1871 } else
1872#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001873 {
1874#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1875 mbedtls_printf(" AES note: built-in implementation.\n");
1876#endif
1877 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001878#endif /* MBEDTLS_AES_ALT */
1879 }
1880
Paul Bakker5121ce52009-01-03 21:22:43 +00001881 /*
1882 * ECB mode
1883 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001884 {
1885 static const int num_tests =
Yanray Wang78ee0c92023-05-15 11:23:50 +08001886 sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);
Paul Bakker5121ce52009-01-03 21:22:43 +00001887
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001888 for (i = 0; i < num_tests << 1; i++) {
1889 u = i >> 1;
1890 keybits = 128 + u * 64;
1891 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001892
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001893 if (verbose != 0) {
1894 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1895 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1896 }
Yanray Wangb67b4742023-10-31 17:10:32 +08001897#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang78ee0c92023-05-15 11:23:50 +08001898 if (mode == MBEDTLS_AES_DECRYPT) {
1899 if (verbose != 0) {
1900 mbedtls_printf("skipped\n");
1901 }
1902 continue;
1903 }
1904#endif
Arto Kinnunen0f066182023-04-20 10:02:46 +08001905
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001906 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001907
Yanray Wangb67b4742023-10-31 17:10:32 +08001908#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001909 if (mode == MBEDTLS_AES_DECRYPT) {
1910 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1911 aes_tests = aes_test_ecb_dec[u];
Yanray Wang78ee0c92023-05-15 11:23:50 +08001912 } else
1913#endif
1914 {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001915 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1916 aes_tests = aes_test_ecb_enc[u];
1917 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001918
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001919 /*
1920 * AES-192 is an optional feature that may be unavailable when
1921 * there is an alternative underlying implementation i.e. when
1922 * MBEDTLS_AES_ALT is defined.
1923 */
1924 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1925 mbedtls_printf("skipped\n");
1926 continue;
1927 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001928 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001929 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001930
1931 for (j = 0; j < 10000; j++) {
1932 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1933 if (ret != 0) {
1934 goto exit;
1935 }
1936 }
1937
1938 if (memcmp(buf, aes_tests, 16) != 0) {
1939 ret = 1;
1940 goto exit;
1941 }
1942
1943 if (verbose != 0) {
1944 mbedtls_printf("passed\n");
1945 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001946 }
1947
Gilles Peskine449bd832023-01-11 14:50:10 +01001948 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001949 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001950 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001951 }
1952
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001953#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001954 /*
1955 * CBC mode
1956 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001957 {
1958 static const int num_tests =
1959 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001960
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001961 for (i = 0; i < num_tests << 1; i++) {
1962 u = i >> 1;
1963 keybits = 128 + u * 64;
1964 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001965
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001966 if (verbose != 0) {
1967 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1968 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001969 }
1970
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001971 memset(iv, 0, 16);
1972 memset(prv, 0, 16);
1973 memset(buf, 0, 16);
1974
1975 if (mode == MBEDTLS_AES_DECRYPT) {
1976 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1977 aes_tests = aes_test_cbc_dec[u];
1978 } else {
1979 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1980 aes_tests = aes_test_cbc_enc[u];
1981 }
1982
1983 /*
1984 * AES-192 is an optional feature that may be unavailable when
1985 * there is an alternative underlying implementation i.e. when
1986 * MBEDTLS_AES_ALT is defined.
1987 */
1988 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1989 mbedtls_printf("skipped\n");
1990 continue;
1991 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001992 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001993 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001994
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001995 for (j = 0; j < 10000; j++) {
1996 if (mode == MBEDTLS_AES_ENCRYPT) {
1997 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001998
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001999 memcpy(tmp, prv, 16);
2000 memcpy(prv, buf, 16);
2001 memcpy(buf, tmp, 16);
2002 }
2003
2004 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2005 if (ret != 0) {
2006 goto exit;
2007 }
2008
2009 }
2010
2011 if (memcmp(buf, aes_tests, 16) != 0) {
2012 ret = 1;
2013 goto exit;
2014 }
2015
2016 if (verbose != 0) {
2017 mbedtls_printf("passed\n");
2018 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002019 }
2020
Gilles Peskine449bd832023-01-11 14:50:10 +01002021 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002022 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002023 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002024 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002025#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002027#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002028 /*
2029 * CFB128 mode
2030 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002031 {
2032 static const int num_tests =
2033 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002034
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002035 for (i = 0; i < num_tests << 1; i++) {
2036 u = i >> 1;
2037 keybits = 128 + u * 64;
2038 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002039
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002040 if (verbose != 0) {
2041 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2042 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2043 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002044
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002045 memcpy(iv, aes_test_cfb128_iv, 16);
2046 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002047
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002048 offset = 0;
2049 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2050 /*
2051 * AES-192 is an optional feature that may be unavailable when
2052 * there is an alternative underlying implementation i.e. when
2053 * MBEDTLS_AES_ALT is defined.
2054 */
2055 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2056 mbedtls_printf("skipped\n");
2057 continue;
2058 } else if (ret != 0) {
2059 goto exit;
2060 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002061
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002062 if (mode == MBEDTLS_AES_DECRYPT) {
2063 memcpy(buf, aes_test_cfb128_ct[u], 64);
2064 aes_tests = aes_test_cfb128_pt;
2065 } else {
2066 memcpy(buf, aes_test_cfb128_pt, 64);
2067 aes_tests = aes_test_cfb128_ct[u];
2068 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002069
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002070 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2071 if (ret != 0) {
2072 goto exit;
2073 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002074
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002075 if (memcmp(buf, aes_tests, 64) != 0) {
2076 ret = 1;
2077 goto exit;
2078 }
2079
2080 if (verbose != 0) {
2081 mbedtls_printf("passed\n");
2082 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002083 }
2084
Gilles Peskine449bd832023-01-11 14:50:10 +01002085 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002086 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002087 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002088 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002090
Simon Butcherad4e4932018-04-29 00:43:47 +01002091#if defined(MBEDTLS_CIPHER_MODE_OFB)
2092 /*
2093 * OFB mode
2094 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002095 {
2096 static const int num_tests =
2097 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002098
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002099 for (i = 0; i < num_tests << 1; i++) {
2100 u = i >> 1;
2101 keybits = 128 + u * 64;
2102 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002103
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002104 if (verbose != 0) {
2105 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2106 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2107 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002108
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002109 memcpy(iv, aes_test_ofb_iv, 16);
2110 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002111
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002112 offset = 0;
2113 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2114 /*
2115 * AES-192 is an optional feature that may be unavailable when
2116 * there is an alternative underlying implementation i.e. when
2117 * MBEDTLS_AES_ALT is defined.
2118 */
2119 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2120 mbedtls_printf("skipped\n");
2121 continue;
2122 } else if (ret != 0) {
2123 goto exit;
2124 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002125
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002126 if (mode == MBEDTLS_AES_DECRYPT) {
2127 memcpy(buf, aes_test_ofb_ct[u], 64);
2128 aes_tests = aes_test_ofb_pt;
2129 } else {
2130 memcpy(buf, aes_test_ofb_pt, 64);
2131 aes_tests = aes_test_ofb_ct[u];
2132 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002133
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002134 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2135 if (ret != 0) {
2136 goto exit;
2137 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002138
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002139 if (memcmp(buf, aes_tests, 64) != 0) {
2140 ret = 1;
2141 goto exit;
2142 }
2143
2144 if (verbose != 0) {
2145 mbedtls_printf("passed\n");
2146 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002147 }
2148
Gilles Peskine449bd832023-01-11 14:50:10 +01002149 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002150 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002151 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002152 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002153#endif /* MBEDTLS_CIPHER_MODE_OFB */
2154
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002155#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002156 /*
2157 * CTR mode
2158 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002159 {
2160 static const int num_tests =
2161 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002162
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002163 for (i = 0; i < num_tests << 1; i++) {
2164 u = i >> 1;
2165 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002166
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002167 if (verbose != 0) {
2168 mbedtls_printf(" AES-CTR-128 (%s): ",
2169 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2170 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002171
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002172 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2173 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002174
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002175 offset = 0;
2176 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2177 goto exit;
2178 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002179
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002180 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002181
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002182 if (mode == MBEDTLS_AES_DECRYPT) {
2183 memcpy(buf, aes_test_ctr_ct[u], len);
2184 aes_tests = aes_test_ctr_pt[u];
2185 } else {
2186 memcpy(buf, aes_test_ctr_pt[u], len);
2187 aes_tests = aes_test_ctr_ct[u];
2188 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002189
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002190 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2191 stream_block, buf, buf);
2192 if (ret != 0) {
2193 goto exit;
2194 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 if (memcmp(buf, aes_tests, len) != 0) {
2197 ret = 1;
2198 goto exit;
2199 }
2200
2201 if (verbose != 0) {
2202 mbedtls_printf("passed\n");
2203 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002204 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002205 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002206
Gilles Peskine449bd832023-01-11 14:50:10 +01002207 if (verbose != 0) {
2208 mbedtls_printf("\n");
2209 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002210#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002211
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002212#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002213 /*
2214 * XTS mode
2215 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002216 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002217 static const int num_tests =
2218 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2219 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002220
Gilles Peskine449bd832023-01-11 14:50:10 +01002221 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002222
Gilles Peskine449bd832023-01-11 14:50:10 +01002223 for (i = 0; i < num_tests << 1; i++) {
2224 const unsigned char *data_unit;
2225 u = i >> 1;
2226 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002227
Gilles Peskine449bd832023-01-11 14:50:10 +01002228 if (verbose != 0) {
2229 mbedtls_printf(" AES-XTS-128 (%s): ",
2230 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2231 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002232
Gilles Peskine449bd832023-01-11 14:50:10 +01002233 memset(key, 0, sizeof(key));
2234 memcpy(key, aes_test_xts_key[u], 32);
2235 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002236
Gilles Peskine449bd832023-01-11 14:50:10 +01002237 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002238
Gilles Peskine449bd832023-01-11 14:50:10 +01002239 if (mode == MBEDTLS_AES_DECRYPT) {
2240 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2241 if (ret != 0) {
2242 goto exit;
2243 }
2244 memcpy(buf, aes_test_xts_ct32[u], len);
2245 aes_tests = aes_test_xts_pt32[u];
2246 } else {
2247 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2248 if (ret != 0) {
2249 goto exit;
2250 }
2251 memcpy(buf, aes_test_xts_pt32[u], len);
2252 aes_tests = aes_test_xts_ct32[u];
2253 }
2254
2255
2256 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2257 buf, buf);
2258 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002259 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002260 }
2261
2262 if (memcmp(buf, aes_tests, len) != 0) {
2263 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002264 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002265 }
2266
2267 if (verbose != 0) {
2268 mbedtls_printf("passed\n");
2269 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002270 }
2271
Gilles Peskine449bd832023-01-11 14:50:10 +01002272 if (verbose != 0) {
2273 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002274 }
2275
Gilles Peskine449bd832023-01-11 14:50:10 +01002276 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002277 }
2278#endif /* MBEDTLS_CIPHER_MODE_XTS */
2279
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002280 ret = 0;
2281
2282exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002283 if (ret != 0 && verbose != 0) {
2284 mbedtls_printf("failed\n");
2285 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002286
Gilles Peskine449bd832023-01-11 14:50:10 +01002287 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002288
Gilles Peskine449bd832023-01-11 14:50:10 +01002289 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002290}
2291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002292#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002294#endif /* MBEDTLS_AES_C */