blob: feb455b6fdbf62d238d1ccb6b3556f485d71f7c1 [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 Rodgmane3c05852023-11-03 12:21:36 +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
Jerry Yu72fd0bd2023-08-18 16:31:01 +080025#if defined(MBEDTLS_ARCH_IS_ARM64)
Jerry Yu02b15192023-04-23 14:43:19 +080026#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080027#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080028#endif
29#endif
30
Jerry Yud6e312d2023-08-18 17:19:51 +080031#if defined(MBEDTLS_ARCH_IS_X64)
Jerry Yu02b15192023-04-23 14:43:19 +080032#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080033#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080034#endif
35#endif
36
Jerry Yud6e312d2023-08-18 17:19:51 +080037#if defined(MBEDTLS_ARCH_IS_X86)
Jerry Yue62ff092023-08-16 14:15:00 +080038#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY) && !defined(MBEDTLS_AESNI_C)
39#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080041
Jerry Yu61fc5ed2023-08-18 17:28:48 +080042#if defined(MBEDTLS_PADLOCK_C)
43#if !defined(MBEDTLS_HAVE_ASM)
Jerry Yu13696bb2023-08-10 13:36:32 +080044#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
45#endif
Jerry Yu61fc5ed2023-08-18 17:28:48 +080046#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
47#error "MBEDTLS_AES_USE_HARDWARE_ONLY cannot be defined when " \
48 "MBEDTLS_PADLOCK_C is set"
49#endif
50#endif
Jerry Yu02b15192023-04-23 14:43:19 +080051#endif
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000054#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000055#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000057#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010058#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080059#if defined(MBEDTLS_AESCE_C)
60#include "aesce.h"
61#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000062
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000063#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010064
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020066
Jerry Yu9e628622023-08-17 11:20:09 +080067#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Paul Bakker048d04e2012-02-12 17:31:04 +000068static int aes_padlock_ace = -1;
69#endif
70
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000072/*
73 * Forward S-box
74 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010075#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
76 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000077static const unsigned char FSb[256] =
78{
79 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
80 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
81 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
82 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
83 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
84 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
85 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
86 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
87 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
88 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
89 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
90 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
91 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
92 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
93 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
94 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
95 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
96 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
97 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
98 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
99 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
100 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
101 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
102 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
103 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
104 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
105 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
106 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
107 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
108 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
109 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
110 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
111};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100112#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
113 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000114
115/*
116 * Forward tables
117 */
118#define FT \
119\
Gilles Peskine449bd832023-01-11 14:50:10 +0100120 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
121 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
122 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
123 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
124 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
125 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
126 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
127 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
128 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
129 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
130 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
131 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
132 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
133 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
134 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
135 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
136 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
137 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
138 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
139 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
140 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
141 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
142 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
143 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
144 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
145 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
146 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
147 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
148 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
149 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
150 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
151 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
152 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
153 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
154 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
155 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
156 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
157 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
158 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
159 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
160 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
161 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
162 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
163 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
164 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
165 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
166 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
167 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
168 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
169 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
170 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
171 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
172 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
173 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
174 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
175 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
176 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
177 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
178 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
179 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
180 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
181 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
182 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
183 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 +0000184
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100185#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100186#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000187static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000188#undef V
189
Hanno Beckerad049a92017-06-19 16:31:54 +0100190#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200191
Gilles Peskine449bd832023-01-11 14:50:10 +0100192#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000193static const uint32_t FT1[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##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000197static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000198#undef V
199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000201static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000202#undef V
203
Hanno Becker177d3cf2017-06-07 15:52:48 +0100204#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200205
Dave Rodgman1be24632023-06-29 12:01:24 +0100206#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
207
Paul Bakker5121ce52009-01-03 21:22:43 +0000208#undef FT
209
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100210#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000211/*
212 * Reverse S-box
213 */
214static const unsigned char RSb[256] =
215{
216 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
217 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
218 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
219 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
220 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
221 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
222 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
223 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
224 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
225 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
226 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
227 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
228 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
229 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
230 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
231 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
232 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
233 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
234 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
235 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
236 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
237 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
238 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
239 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
240 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
241 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
242 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
243 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
244 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
245 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
246 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
247 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
248};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100249#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000250
251/*
252 * Reverse tables
253 */
254#define RT \
255\
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
257 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
258 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
259 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
260 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
261 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
262 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
263 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
264 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
265 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
266 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
267 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
268 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
269 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
270 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
271 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
272 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
273 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
274 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
275 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
276 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
277 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
278 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
279 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
280 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
281 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
282 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
283 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
284 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
285 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
286 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
287 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
288 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
289 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
290 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
291 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
292 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
293 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
294 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
295 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
296 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
297 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
298 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
299 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
300 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
301 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
302 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
303 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
304 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
305 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
306 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
307 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
308 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
309 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
310 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
311 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
312 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
313 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
314 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
315 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
316 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
317 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
318 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
319 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 +0000320
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100321#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000324static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000325#undef V
326
Hanno Beckerad049a92017-06-19 16:31:54 +0100327#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200328
Gilles Peskine449bd832023-01-11 14:50:10 +0100329#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000330static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000331#undef V
332
Gilles Peskine449bd832023-01-11 14:50:10 +0100333#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000335#undef V
336
Gilles Peskine449bd832023-01-11 14:50:10 +0100337#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000338static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000339#undef V
340
Hanno Becker177d3cf2017-06-07 15:52:48 +0100341#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200342
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800343#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
344
Paul Bakker5121ce52009-01-03 21:22:43 +0000345#undef RT
346
Dave Rodgman34152a42023-06-27 18:31:24 +0100347#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000348/*
349 * Round constants
350 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000352{
353 0x00000001, 0x00000002, 0x00000004, 0x00000008,
354 0x00000010, 0x00000020, 0x00000040, 0x00000080,
355 0x0000001B, 0x00000036
356};
Dave Rodgman34152a42023-06-27 18:31:24 +0100357#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000358
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
361/*
362 * Forward S-box & tables
363 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100364#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
365 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000366static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100367#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
368 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100369#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200370static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100371#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200372static uint32_t FT1[256];
373static uint32_t FT2[256];
374static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100375#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100376#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000377
378/*
379 * Reverse S-box & tables
380 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100381#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000382static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100383#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100384
385#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000386static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100387#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000388static uint32_t RT1[256];
389static uint32_t RT2[256];
390static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100391#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100392#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000393
Dave Rodgman8c753f92023-06-27 18:16:13 +0100394#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000395/*
396 * Round constants
397 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000398static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
400/*
401 * Tables generation code
402 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100403#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
404#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
405#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
407static int aes_init_done = 0;
408
Gilles Peskine449bd832023-01-11 14:50:10 +0100409static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000410{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800411 int i;
412 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800413 uint8_t pow[256];
414 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
416 /*
417 * compute pow and log tables over GF(2^8)
418 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800421 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800422 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 }
424
425 /*
426 * calculate the round constants
427 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800429 RCON[i] = x;
430 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 }
432
433 /*
434 * generate the forward and reverse S-boxes
435 */
436 FSb[0x00] = 0x63;
437 RSb[0x63] = 0x00;
438
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 x = pow[255 - log[i]];
441
Yanray Wangfe944ce2023-06-26 18:16:01 +0800442 y = x; y = (y << 1) | (y >> 7);
443 x ^= y; y = (y << 1) | (y >> 7);
444 x ^= y; y = (y << 1) | (y >> 7);
445 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 x ^= y ^ 0x63;
447
Yanray Wangfe944ce2023-06-26 18:16:01 +0800448 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 RSb[x] = (unsigned char) i;
450 }
451
452 /*
453 * generate the forward and reverse tables
454 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800457 y = XTIME(x);
458 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 FT0[i] = ((uint32_t) y) ^
461 ((uint32_t) x << 8) ^
462 ((uint32_t) x << 16) ^
463 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000464
Hanno Beckerad049a92017-06-19 16:31:54 +0100465#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 FT1[i] = ROTL8(FT0[i]);
467 FT2[i] = ROTL8(FT1[i]);
468 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100469#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
471 x = RSb[i];
472
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100473#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
475 ((uint32_t) MUL(0x09, x) << 8) ^
476 ((uint32_t) MUL(0x0D, x) << 16) ^
477 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
Hanno Beckerad049a92017-06-19 16:31:54 +0100479#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 RT1[i] = ROTL8(RT0[i]);
481 RT2[i] = ROTL8(RT1[i]);
482 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100483#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100484#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000485 }
486}
487
Dave Rodgman8c753f92023-06-27 18:16:13 +0100488#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
489
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200490#undef ROTL8
491
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000493
Hanno Beckerad049a92017-06-19 16:31:54 +0100494#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
497#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
498#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200499
500#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100501#define AES_RT1(idx) ROTL8(RT0[idx])
502#define AES_RT2(idx) ROTL16(RT0[idx])
503#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200504
505#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100506#define AES_FT1(idx) ROTL8(FT0[idx])
507#define AES_FT2(idx) ROTL16(FT0[idx])
508#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200509
Hanno Becker177d3cf2017-06-07 15:52:48 +0100510#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200511
512#define AES_RT0(idx) RT0[idx]
513#define AES_RT1(idx) RT1[idx]
514#define AES_RT2(idx) RT2[idx]
515#define AES_RT3(idx) RT3[idx]
516
517#define AES_FT0(idx) FT0[idx]
518#define AES_FT1(idx) FT1[idx]
519#define AES_FT2(idx) FT2[idx]
520#define AES_FT3(idx) FT3[idx]
521
Hanno Becker177d3cf2017-06-07 15:52:48 +0100522#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200523
Gilles Peskine449bd832023-01-11 14:50:10 +0100524void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200525{
Gilles Peskine449bd832023-01-11 14:50:10 +0100526 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200527}
528
Gilles Peskine449bd832023-01-11 14:50:10 +0100529void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200530{
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200532 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200536}
537
Jaeden Amero9366feb2018-05-29 18:55:17 +0100538#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100539void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100540{
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 mbedtls_aes_init(&ctx->crypt);
542 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100543}
544
Gilles Peskine449bd832023-01-11 14:50:10 +0100545void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100546{
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100548 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100549 }
Simon Butcher5201e412018-12-06 17:40:14 +0000550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 mbedtls_aes_free(&ctx->crypt);
552 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100553}
554#endif /* MBEDTLS_CIPHER_MODE_XTS */
555
Gilles Peskine0de8f852023-03-16 17:14:59 +0100556/* Some implementations need the round keys to be aligned.
557 * Return an offset to be added to buf, such that (buf + offset) is
558 * correctly aligned.
559 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
560 * i.e. an offset of 1 means 4 bytes and so on.
561 */
Jerry Yu96084472023-08-17 18:10:45 +0800562#if (defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100563 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100564#define MAY_NEED_TO_ALIGN
565#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100566
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100567#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
568 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100569static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
570{
571#if defined(MAY_NEED_TO_ALIGN)
572 int align_16_bytes = 0;
573
Jerry Yu9e628622023-08-17 11:20:09 +0800574#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100575 if (aes_padlock_ace == -1) {
576 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
577 }
578 if (aes_padlock_ace) {
579 align_16_bytes = 1;
580 }
581#endif
582
Gilles Peskine9c682e72023-03-16 17:21:33 +0100583#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100584 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
585 align_16_bytes = 1;
586 }
587#endif
588
589 if (align_16_bytes) {
590 /* These implementations needs 16-byte alignment
591 * for the round key array. */
592 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
593 if (delta == 0) {
594 return 0;
595 } else {
596 return 4 - delta; // 16 bytes = 4 uint32_t
597 }
598 }
599#else /* MAY_NEED_TO_ALIGN */
600 (void) buf;
601#endif /* MAY_NEED_TO_ALIGN */
602
603 return 0;
604}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100605#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
606 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100607
Paul Bakker5121ce52009-01-03 21:22:43 +0000608/*
609 * AES key schedule (encryption)
610 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200611#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100612int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
613 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000614{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000615 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000618 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800619#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000620 case 192: ctx->nr = 12; break;
621 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800622#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 }
625
Simon Butcher5201e412018-12-06 17:40:14 +0000626#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000628 aes_gen_tables();
629 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000630 }
631#endif
632
Gilles Peskine0de8f852023-03-16 17:14:59 +0100633 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100634 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100636#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
638 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
639 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100640#endif
641
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800642#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100643 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu3f2fb712023-01-10 17:05:42 +0800644 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
645 }
646#endif
647
Jerry Yu29c91ba2023-08-04 11:02:04 +0800648#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu3a0f0442023-08-17 17:06:21 +0800649 for (unsigned int i = 0; i < (keybits >> 5); i++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 }
652
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 case 10:
655
Jerry Yu3a0f0442023-08-17 17:06:21 +0800656 for (unsigned int i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
659 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
660 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
661 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
663 RK[5] = RK[1] ^ RK[4];
664 RK[6] = RK[2] ^ RK[5];
665 RK[7] = RK[3] ^ RK[6];
666 }
667 break;
668
Arto Kinnunen732ca322023-04-14 14:26:10 +0800669#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 case 12:
671
Jerry Yu3a0f0442023-08-17 17:06:21 +0800672 for (unsigned int i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
675 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
676 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
677 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
679 RK[7] = RK[1] ^ RK[6];
680 RK[8] = RK[2] ^ RK[7];
681 RK[9] = RK[3] ^ RK[8];
682 RK[10] = RK[4] ^ RK[9];
683 RK[11] = RK[5] ^ RK[10];
684 }
685 break;
686
687 case 14:
688
Jerry Yu3a0f0442023-08-17 17:06:21 +0800689 for (unsigned int i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000690 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100691 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
692 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
693 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
694 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
696 RK[9] = RK[1] ^ RK[8];
697 RK[10] = RK[2] ^ RK[9];
698 RK[11] = RK[3] ^ RK[10];
699
700 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100701 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
702 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
703 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
704 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
706 RK[13] = RK[5] ^ RK[12];
707 RK[14] = RK[6] ^ RK[13];
708 RK[15] = RK[7] ^ RK[14];
709 }
710 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800711#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000712 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800715#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000716}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200717#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000718
719/*
720 * AES key schedule (decryption)
721 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200722#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100723int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
724 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000725{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800726#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu29c91ba2023-08-04 11:02:04 +0800727 uint32_t *SK;
728#endif
729 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200730 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000731 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800732
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000735
Gilles Peskine0de8f852023-03-16 17:14:59 +0100736 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100737 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000738
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200739 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200741 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000743
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200744 ctx->nr = cty.nr;
745
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100746#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100747 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
748 mbedtls_aesni_inverse_key((unsigned char *) RK,
749 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200750 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100751 }
752#endif
753
Jerry Yu72fd0bd2023-08-18 16:31:01 +0800754#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +0100755 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yue096da12023-01-10 17:07:01 +0800756 mbedtls_aesce_inverse_key(
757 (unsigned char *) RK,
758 (const unsigned char *) (cty.buf + cty.rk_offset),
759 ctx->nr);
760 goto exit;
761 }
762#endif
763
Jerry Yu29c91ba2023-08-04 11:02:04 +0800764#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100765 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000766
767 *RK++ = *SK++;
768 *RK++ = *SK++;
769 *RK++ = *SK++;
770 *RK++ = *SK++;
Jerry Yu3a0f0442023-08-17 17:06:21 +0800771 SK -= 8;
772 for (int i = ctx->nr - 1; i > 0; i--, SK -= 8) {
773 for (int j = 0; j < 4; j++, SK++) {
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
775 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
776 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
777 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000778 }
779 }
780
781 *RK++ = *SK++;
782 *RK++ = *SK++;
783 *RK++ = *SK++;
784 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800785#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200786exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100787 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000788
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000790}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100791#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100792
793#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100794static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
795 unsigned int keybits,
796 const unsigned char **key1,
797 unsigned int *key1bits,
798 const unsigned char **key2,
799 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100800{
801 const unsigned int half_keybits = keybits / 2;
802 const unsigned int half_keybytes = half_keybits / 8;
803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100805 case 256: break;
806 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100808 }
809
810 *key1bits = half_keybits;
811 *key2bits = half_keybits;
812 *key1 = &key[0];
813 *key2 = &key[half_keybytes];
814
815 return 0;
816}
817
Gilles Peskine449bd832023-01-11 14:50:10 +0100818int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
819 const unsigned char *key,
820 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100821{
Janos Follath24eed8d2019-11-22 13:21:35 +0000822 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100823 const unsigned char *key1, *key2;
824 unsigned int key1bits, key2bits;
825
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
827 &key2, &key2bits);
828 if (ret != 0) {
829 return ret;
830 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100831
832 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
834 if (ret != 0) {
835 return ret;
836 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100837
838 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100839 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100840}
841
Gilles Peskine449bd832023-01-11 14:50:10 +0100842int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
843 const unsigned char *key,
844 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100845{
Janos Follath24eed8d2019-11-22 13:21:35 +0000846 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100847 const unsigned char *key1, *key2;
848 unsigned int key1bits, key2bits;
849
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
851 &key2, &key2bits);
852 if (ret != 0) {
853 return ret;
854 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100855
856 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100857 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
858 if (ret != 0) {
859 return ret;
860 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100861
862 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100864}
865#endif /* MBEDTLS_CIPHER_MODE_XTS */
866
Gilles Peskine449bd832023-01-11 14:50:10 +0100867#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100868 do \
869 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100870 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
871 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
872 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
873 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100874 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
876 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
877 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
878 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100879 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
881 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
882 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
883 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100884 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
886 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
887 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
888 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
889 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100892 do \
893 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100894 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
895 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
896 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
897 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100898 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100899 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
900 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
901 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
902 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100903 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
905 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
906 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
907 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100908 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
910 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
911 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
912 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
913 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000914
915/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200916 * AES-ECB block encryption
917 */
918#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100919int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
920 const unsigned char input[16],
921 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200922{
923 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100924 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100925 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200926 uint32_t X[4];
927 uint32_t Y[4];
928 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
931 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
932 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
933 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
936 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]);
937 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 +0200938 }
939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 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 +0200941
Gilles Peskine5197c662020-08-26 17:03:24 +0200942 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100943 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
944 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
945 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
946 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200947
Gilles Peskine5197c662020-08-26 17:03:24 +0200948 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
950 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
951 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
952 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200953
Gilles Peskine5197c662020-08-26 17:03:24 +0200954 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
956 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
957 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
958 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200959
Gilles Peskine5197c662020-08-26 17:03:24 +0200960 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
963 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
964 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200965
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
967 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
968 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
969 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000970
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500972
Gilles Peskine449bd832023-01-11 14:50:10 +0100973 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200974}
975#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
976
977/*
978 * AES-ECB block decryption
979 */
980#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100981int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
982 const unsigned char input[16],
983 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200984{
985 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100986 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200988 uint32_t X[4];
989 uint32_t Y[4];
990 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200991
Gilles Peskine449bd832023-01-11 14:50:10 +0100992 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
993 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
994 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
995 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200996
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
998 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]);
999 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 +02001000 }
1001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 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 +02001003
Gilles Peskine5197c662020-08-26 17:03:24 +02001004 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001005 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1006 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1007 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1008 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001009
Gilles Peskine5197c662020-08-26 17:03:24 +02001010 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1012 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1013 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1014 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001015
Gilles Peskine5197c662020-08-26 17:03:24 +02001016 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1018 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1019 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1020 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001021
Gilles Peskine5197c662020-08-26 17:03:24 +02001022 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1025 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1026 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001027
Gilles Peskine449bd832023-01-11 14:50:10 +01001028 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1029 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1030 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1031 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001032
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001036}
1037#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1038
Gilles Peskine0de8f852023-03-16 17:14:59 +01001039#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001040/* VIA Padlock and our intrinsics-based implementation of AESNI require
1041 * the round keys to be aligned on a 16-byte boundary. We take care of this
1042 * before creating them, but the AES context may have moved (this can happen
1043 * if the library is called from a language with managed memory), and in later
1044 * calls it might have a different alignment with respect to 16-byte memory.
1045 * So we may need to realign.
1046 */
1047static void aes_maybe_realign(mbedtls_aes_context *ctx)
1048{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001049 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1050 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001051 memmove(ctx->buf + new_offset, // new address
1052 ctx->buf + ctx->rk_offset, // current address
1053 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1054 ctx->rk_offset = new_offset;
1055 }
1056}
1057#endif
1058
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001059/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001060 * AES-ECB block encryption/decryption
1061 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001062int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1063 int mode,
1064 const unsigned char input[16],
1065 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001066{
Gilles Peskine449bd832023-01-11 14:50:10 +01001067 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001068 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001069 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001070
Gilles Peskine0de8f852023-03-16 17:14:59 +01001071#if defined(MAY_NEED_TO_ALIGN)
1072 aes_maybe_realign(ctx);
1073#endif
1074
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001075#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1077 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1078 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001079#endif
1080
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001081#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001082 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Jerry Yu2bb3d812023-01-10 17:38:26 +08001083 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1084 }
1085#endif
1086
Jerry Yu9e628622023-08-17 11:20:09 +08001087#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001089 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001090 }
1091#endif
1092
Jerry Yu29c91ba2023-08-04 11:02:04 +08001093#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 if (mode == MBEDTLS_AES_ENCRYPT) {
1095 return mbedtls_internal_aes_encrypt(ctx, input, output);
1096 } else {
1097 return mbedtls_internal_aes_decrypt(ctx, input, output);
1098 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001099#endif
1100
Paul Bakker5121ce52009-01-03 21:22:43 +00001101}
1102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001104
Paul Bakker5121ce52009-01-03 21:22:43 +00001105/*
1106 * AES-CBC buffer encryption/decryption
1107 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001108int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1109 int mode,
1110 size_t length,
1111 unsigned char iv[16],
1112 const unsigned char *input,
1113 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001114{
Gilles Peskine7820a572021-07-07 21:08:28 +02001115 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001116 unsigned char temp[16];
1117
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001119 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001121
Paul Elliott2ad93672023-08-11 11:07:06 +01001122 /* Nothing to do if length is zero. */
1123 if (length == 0) {
1124 return 0;
1125 }
1126
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 if (length % 16) {
1128 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1129 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001130
Jerry Yu9e628622023-08-17 11:20:09 +08001131#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 if (aes_padlock_ace > 0) {
1133 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1134 return 0;
1135 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001136
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001137 // If padlock data misaligned, we just fall back to
1138 // unaccelerated mode
1139 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001140 }
1141#endif
1142
Dave Rodgman906c63c2023-06-14 17:53:51 +01001143 const unsigned char *ivp = iv;
1144
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 if (mode == MBEDTLS_AES_DECRYPT) {
1146 while (length > 0) {
1147 memcpy(temp, input, 16);
1148 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1149 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001150 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001152 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001153 * the result for the next block in CBC, and the cost of transferring that data from
1154 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001155 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001156
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001158
1159 input += 16;
1160 output += 16;
1161 length -= 16;
1162 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 } else {
1164 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001165 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001166
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1168 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001169 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001171 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001172
1173 input += 16;
1174 output += 16;
1175 length -= 16;
1176 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001177 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001178 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001179 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001180
Gilles Peskine7820a572021-07-07 21:08:28 +02001181exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001183}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001184#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001185
Aorimn5f778012016-06-09 23:22:58 +02001186#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001187
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001188typedef unsigned char mbedtls_be128[16];
1189
1190/*
1191 * GF(2^128) multiplication function
1192 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001193 * This function multiplies a field element by x in the polynomial field
1194 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001195 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001196 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001197 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001198#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001199MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001200#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001201static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001202 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001203{
1204 uint64_t a, b, ra, rb;
1205
Gilles Peskine449bd832023-01-11 14:50:10 +01001206 a = MBEDTLS_GET_UINT64_LE(x, 0);
1207 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001208
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1210 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001211
Gilles Peskine449bd832023-01-11 14:50:10 +01001212 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1213 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001214}
1215
Aorimn5f778012016-06-09 23:22:58 +02001216/*
1217 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001218 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001219 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001220 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001221 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001222#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001223MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001224#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001225int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1226 int mode,
1227 size_t length,
1228 const unsigned char data_unit[16],
1229 const unsigned char *input,
1230 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001231{
Janos Follath24eed8d2019-11-22 13:21:35 +00001232 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001233 size_t blocks = length / 16;
1234 size_t leftover = length % 16;
1235 unsigned char tweak[16];
1236 unsigned char prev_tweak[16];
1237 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001238
Gilles Peskine449bd832023-01-11 14:50:10 +01001239 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001240 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001242
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001243 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001245 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 }
Aorimn5f778012016-06-09 23:22:58 +02001247
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001248 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001250 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 }
Aorimn5f778012016-06-09 23:22:58 +02001252
Jaeden Amerod82cd862018-04-28 15:02:45 +01001253 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1255 data_unit, tweak);
1256 if (ret != 0) {
1257 return ret;
1258 }
Aorimn5f778012016-06-09 23:22:58 +02001259
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001261 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001262 /* We are on the last block in a decrypt operation that has
1263 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001264 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001265 * the leftovers and then update the current tweak for use on this,
1266 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001267 memcpy(prev_tweak, tweak, sizeof(tweak));
1268 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001269 }
1270
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001272
Gilles Peskine449bd832023-01-11 14:50:10 +01001273 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1274 if (ret != 0) {
1275 return ret;
1276 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001277
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001279
1280 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282
1283 output += 16;
1284 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001285 }
1286
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001288 /* If we are on the leftover bytes in a decrypt operation, we need to
1289 * use the previous tweak for these bytes (as saved in prev_tweak). */
1290 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001291
Jaeden Amerod82cd862018-04-28 15:02:45 +01001292 /* We are now on the final part of the data unit, which doesn't divide
1293 * evenly by 16. It's time for ciphertext stealing. */
1294 size_t i;
1295 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001296
Jaeden Amerod82cd862018-04-28 15:02:45 +01001297 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001298 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001299 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001300 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001301 }
Aorimn5f778012016-06-09 23:22:58 +02001302
Dave Rodgman069e7f42022-11-24 19:37:26 +00001303 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001304 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001305
Jaeden Amerod82cd862018-04-28 15:02:45 +01001306 /* Copy ciphertext bytes from the previous block for input in this
1307 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001308 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001309
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1311 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001312 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 }
Aorimn5f778012016-06-09 23:22:58 +02001314
Jaeden Amerod82cd862018-04-28 15:02:45 +01001315 /* Write the result back to the previous block, overriding the previous
1316 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001318 }
1319
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001321}
1322#endif /* MBEDTLS_CIPHER_MODE_XTS */
1323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001324#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001325/*
1326 * AES-CFB128 buffer encryption/decryption
1327 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001328int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1329 int mode,
1330 size_t length,
1331 size_t *iv_off,
1332 unsigned char iv[16],
1333 const unsigned char *input,
1334 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001335{
Paul Bakker27fdf462011-06-09 13:55:13 +00001336 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001337 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001338 size_t n;
1339
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001341 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001342 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001343
1344 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001345
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 if (n > 15) {
1347 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1348 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001349
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 if (mode == MBEDTLS_AES_DECRYPT) {
1351 while (length--) {
1352 if (n == 0) {
1353 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1354 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001355 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001356 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001357 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001358
1359 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 iv[n] = (unsigned char) c;
1362
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001364 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 } else {
1366 while (length--) {
1367 if (n == 0) {
1368 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1369 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001370 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001372 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001373
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001375
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001377 }
1378 }
1379
1380 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001381 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001382
Gilles Peskine7820a572021-07-07 21:08:28 +02001383exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001385}
Paul Bakker556efba2014-01-24 15:38:12 +01001386
1387/*
1388 * AES-CFB8 buffer encryption/decryption
1389 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001390int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1391 int mode,
1392 size_t length,
1393 unsigned char iv[16],
1394 const unsigned char *input,
1395 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001396{
Gilles Peskine7820a572021-07-07 21:08:28 +02001397 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001398 unsigned char c;
1399 unsigned char ov[17];
1400
Gilles Peskine449bd832023-01-11 14:50:10 +01001401 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001402 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001403 }
1404 while (length--) {
1405 memcpy(ov, iv, 16);
1406 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1407 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001408 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001409 }
Paul Bakker556efba2014-01-24 15:38:12 +01001410
Gilles Peskine449bd832023-01-11 14:50:10 +01001411 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001412 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001413 }
Paul Bakker556efba2014-01-24 15:38:12 +01001414
Gilles Peskine449bd832023-01-11 14:50:10 +01001415 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001416
Gilles Peskine449bd832023-01-11 14:50:10 +01001417 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001418 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 }
Paul Bakker556efba2014-01-24 15:38:12 +01001420
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001422 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001423 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001424
Gilles Peskine7820a572021-07-07 21:08:28 +02001425exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001426 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001427}
Simon Butcher76a5b222018-04-22 22:57:27 +01001428#endif /* MBEDTLS_CIPHER_MODE_CFB */
1429
1430#if defined(MBEDTLS_CIPHER_MODE_OFB)
1431/*
1432 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1433 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001434int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1435 size_t length,
1436 size_t *iv_off,
1437 unsigned char iv[16],
1438 const unsigned char *input,
1439 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001440{
Simon Butcherad4e4932018-04-29 00:43:47 +01001441 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001442 size_t n;
1443
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001444 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001445
Gilles Peskine449bd832023-01-11 14:50:10 +01001446 if (n > 15) {
1447 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1448 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001449
Gilles Peskine449bd832023-01-11 14:50:10 +01001450 while (length--) {
1451 if (n == 0) {
1452 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1453 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001454 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001455 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001456 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001457 *output++ = *input++ ^ iv[n];
1458
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001460 }
1461
1462 *iv_off = n;
1463
Simon Butcherad4e4932018-04-29 00:43:47 +01001464exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001465 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001466}
1467#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001468
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001469#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001470/*
1471 * AES-CTR buffer encryption/decryption
1472 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001473int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1474 size_t length,
1475 size_t *nc_off,
1476 unsigned char nonce_counter[16],
1477 unsigned char stream_block[16],
1478 const unsigned char *input,
1479 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001480{
Paul Bakker369e14b2012-04-18 14:16:09 +00001481 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001482 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001483 size_t n;
1484
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001485 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001486
Gilles Peskine449bd832023-01-11 14:50:10 +01001487 if (n > 0x0F) {
1488 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1489 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001490
Gilles Peskine449bd832023-01-11 14:50:10 +01001491 while (length--) {
1492 if (n == 0) {
1493 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1494 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001495 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001496 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001497
Gilles Peskine449bd832023-01-11 14:50:10 +01001498 for (i = 16; i > 0; i--) {
1499 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001500 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001501 }
1502 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001503 }
1504 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001505 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001506
Gilles Peskine449bd832023-01-11 14:50:10 +01001507 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001508 }
1509
1510 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001511 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001512
Gilles Peskine7820a572021-07-07 21:08:28 +02001513exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001514 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001515}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001516#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001519
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001520#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001521/*
1522 * AES test vectors from:
1523 *
1524 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1525 */
Yanray Wang62c99912023-05-11 11:06:53 +08001526static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001527{
1528 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1529 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001530#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001531 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1532 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1533 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1534 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001535#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001536};
1537
Yanray Wang62c99912023-05-11 11:06:53 +08001538static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001539{
1540 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1541 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001542#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001543 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1544 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1545 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1546 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001547#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001548};
1549
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001550#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001551static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001552{
1553 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1554 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001555#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001556 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1557 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1558 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1559 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001560#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001561};
1562
Yanray Wang62c99912023-05-11 11:06:53 +08001563static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001564{
1565 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1566 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001567#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001568 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1569 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1570 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1571 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001572#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001573};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001574#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001575
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001576#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001577/*
1578 * AES-CFB128 test vectors from:
1579 *
1580 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1581 */
Yanray Wang62c99912023-05-11 11:06:53 +08001582static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001583{
1584 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1585 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001586#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001587 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1588 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1589 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1590 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1591 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1592 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1593 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001594#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001595};
1596
1597static const unsigned char aes_test_cfb128_iv[16] =
1598{
1599 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1600 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1601};
1602
1603static const unsigned char aes_test_cfb128_pt[64] =
1604{
1605 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1606 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1607 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1608 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1609 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1610 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1611 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1612 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1613};
1614
Yanray Wang62c99912023-05-11 11:06:53 +08001615static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001616{
1617 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1618 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1619 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1620 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1621 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1622 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1623 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1624 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001625#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001626 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1627 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1628 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1629 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1630 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1631 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1632 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1633 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1634 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1635 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1636 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1637 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1638 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1639 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1640 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1641 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001642#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001643};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001644#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001645
Simon Butcherad4e4932018-04-29 00:43:47 +01001646#if defined(MBEDTLS_CIPHER_MODE_OFB)
1647/*
1648 * AES-OFB test vectors from:
1649 *
Simon Butcher5db13622018-06-04 22:11:25 +01001650 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001651 */
Yanray Wang62c99912023-05-11 11:06:53 +08001652static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001653{
1654 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1655 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001656#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001657 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1658 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1659 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1660 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1661 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1662 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1663 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001664#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001665};
1666
1667static const unsigned char aes_test_ofb_iv[16] =
1668{
1669 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1670 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1671};
1672
1673static const unsigned char aes_test_ofb_pt[64] =
1674{
1675 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1676 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1677 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1678 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1679 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1680 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1681 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1682 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1683};
1684
Yanray Wang62c99912023-05-11 11:06:53 +08001685static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001686{
1687 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1688 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1689 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1690 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1691 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1692 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1693 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1694 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001695#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001696 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1697 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1698 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1699 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1700 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1701 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1702 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1703 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1704 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1705 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1706 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1707 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1708 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1709 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1710 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1711 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001712#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001713};
1714#endif /* MBEDTLS_CIPHER_MODE_OFB */
1715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001716#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001717/*
1718 * AES-CTR test vectors from:
1719 *
1720 * http://www.faqs.org/rfcs/rfc3686.html
1721 */
1722
Yanray Wang62c99912023-05-11 11:06:53 +08001723static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001724{
1725 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1726 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1727 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1728 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1729 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1730 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1731};
1732
Yanray Wang62c99912023-05-11 11:06:53 +08001733static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001734{
1735 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1737 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1738 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1739 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1740 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1741};
1742
Yanray Wang62c99912023-05-11 11:06:53 +08001743static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001744{
1745 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1746 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001747 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1748 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1749 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1750 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1751
1752 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1753 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1754 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1755 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1756 0x20, 0x21, 0x22, 0x23 }
1757};
1758
Yanray Wang62c99912023-05-11 11:06:53 +08001759static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001760{
1761 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1762 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1763 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1764 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1765 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1766 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1767 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1768 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1769 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1770 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1771 0x25, 0xB2, 0x07, 0x2F }
1772};
1773
1774static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001775{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001776#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001777
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001778#if defined(MBEDTLS_CIPHER_MODE_XTS)
1779/*
1780 * AES-XTS test vectors from:
1781 *
1782 * IEEE P1619/D16 Annex B
1783 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1784 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1785 */
1786static const unsigned char aes_test_xts_key[][32] =
1787{
1788 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1789 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1792 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1793 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1794 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1795 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1796 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1797 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1798 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1799 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1800};
1801
1802static const unsigned char aes_test_xts_pt32[][32] =
1803{
1804 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1805 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1808 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1809 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1810 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1811 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1812 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1813 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1814 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1815 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1816};
1817
1818static const unsigned char aes_test_xts_ct32[][32] =
1819{
1820 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1821 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1822 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1823 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1824 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1825 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1826 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1827 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1828 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1829 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1830 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1831 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1832};
1833
1834static const unsigned char aes_test_xts_data_unit[][16] =
1835{
Gilles Peskine449bd832023-01-11 14:50:10 +01001836 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1838 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1840 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001842};
1843
1844#endif /* MBEDTLS_CIPHER_MODE_XTS */
1845
Paul Bakker5121ce52009-01-03 21:22:43 +00001846/*
1847 * Checkup routine
1848 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001849int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001850{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001851 int ret = 0, i, j, u, mode;
1852 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001853 unsigned char key[32];
1854 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001855 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001856#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1857 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001858 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001859#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001860#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001861 unsigned char prv[16];
1862#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001863#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1864 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001865 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001866#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001867#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001868 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001869#endif
1870#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001871 unsigned char nonce_counter[16];
1872 unsigned char stream_block[16];
1873#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001874 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
Gilles Peskine449bd832023-01-11 14:50:10 +01001876 memset(key, 0, 32);
1877 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001879 if (verbose != 0) {
1880#if defined(MBEDTLS_AES_ALT)
1881 mbedtls_printf(" AES note: alternative implementation.\n");
1882#else /* MBEDTLS_AES_ALT */
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001883#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001884#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001885 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001886#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001887 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001888#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001889#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001890#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001891 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1892 mbedtls_printf(" AES note: using AESNI.\n");
1893 } else
1894#endif
Jerry Yu9e628622023-08-17 11:20:09 +08001895#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Jerry Yu2319af02023-08-17 10:38:57 +08001896 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1897 mbedtls_printf(" AES note: using VIA Padlock.\n");
1898 } else
1899#endif
Jerry Yu72fd0bd2023-08-18 16:31:01 +08001900#if defined(MBEDTLS_AESCE_HAVE_CODE)
Dave Rodgmanf2249ec2023-08-04 14:27:58 +01001901 if (MBEDTLS_AESCE_HAS_SUPPORT()) {
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001902 mbedtls_printf(" AES note: using AESCE.\n");
1903 } else
1904#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001905 {
1906#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1907 mbedtls_printf(" AES note: built-in implementation.\n");
1908#endif
1909 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001910#endif /* MBEDTLS_AES_ALT */
1911 }
1912
Paul Bakker5121ce52009-01-03 21:22:43 +00001913 /*
1914 * ECB mode
1915 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001916 {
1917 static const int num_tests =
1918 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001919
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001920 for (i = 0; i < num_tests << 1; i++) {
1921 u = i >> 1;
1922 keybits = 128 + u * 64;
1923 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001924
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001925 if (verbose != 0) {
1926 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1927 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1928 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001929
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001930 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001931
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001932 if (mode == MBEDTLS_AES_DECRYPT) {
1933 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1934 aes_tests = aes_test_ecb_dec[u];
1935 } else {
1936 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1937 aes_tests = aes_test_ecb_enc[u];
1938 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001939
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001940 /*
1941 * AES-192 is an optional feature that may be unavailable when
1942 * there is an alternative underlying implementation i.e. when
1943 * MBEDTLS_AES_ALT is defined.
1944 */
1945 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1946 mbedtls_printf("skipped\n");
1947 continue;
1948 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001949 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001950 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001951
1952 for (j = 0; j < 10000; j++) {
1953 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1954 if (ret != 0) {
1955 goto exit;
1956 }
1957 }
1958
1959 if (memcmp(buf, aes_tests, 16) != 0) {
1960 ret = 1;
1961 goto exit;
1962 }
1963
1964 if (verbose != 0) {
1965 mbedtls_printf("passed\n");
1966 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001967 }
1968
Gilles Peskine449bd832023-01-11 14:50:10 +01001969 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001970 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001971 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001972 }
1973
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001974#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001975 /*
1976 * CBC mode
1977 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001978 {
1979 static const int num_tests =
1980 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001981
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001982 for (i = 0; i < num_tests << 1; i++) {
1983 u = i >> 1;
1984 keybits = 128 + u * 64;
1985 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001986
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001987 if (verbose != 0) {
1988 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1989 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001990 }
1991
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001992 memset(iv, 0, 16);
1993 memset(prv, 0, 16);
1994 memset(buf, 0, 16);
1995
1996 if (mode == MBEDTLS_AES_DECRYPT) {
1997 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1998 aes_tests = aes_test_cbc_dec[u];
1999 } else {
2000 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2001 aes_tests = aes_test_cbc_enc[u];
2002 }
2003
2004 /*
2005 * AES-192 is an optional feature that may be unavailable when
2006 * there is an alternative underlying implementation i.e. when
2007 * MBEDTLS_AES_ALT is defined.
2008 */
2009 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2010 mbedtls_printf("skipped\n");
2011 continue;
2012 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002013 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002014 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002015
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002016 for (j = 0; j < 10000; j++) {
2017 if (mode == MBEDTLS_AES_ENCRYPT) {
2018 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002019
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002020 memcpy(tmp, prv, 16);
2021 memcpy(prv, buf, 16);
2022 memcpy(buf, tmp, 16);
2023 }
2024
2025 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2026 if (ret != 0) {
2027 goto exit;
2028 }
2029
2030 }
2031
2032 if (memcmp(buf, aes_tests, 16) != 0) {
2033 ret = 1;
2034 goto exit;
2035 }
2036
2037 if (verbose != 0) {
2038 mbedtls_printf("passed\n");
2039 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002040 }
2041
Gilles Peskine449bd832023-01-11 14:50:10 +01002042 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002043 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002044 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002045 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002046#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002048#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002049 /*
2050 * CFB128 mode
2051 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002052 {
2053 static const int num_tests =
2054 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002055
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002056 for (i = 0; i < num_tests << 1; i++) {
2057 u = i >> 1;
2058 keybits = 128 + u * 64;
2059 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002060
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002061 if (verbose != 0) {
2062 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2063 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2064 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002065
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002066 memcpy(iv, aes_test_cfb128_iv, 16);
2067 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002068
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002069 offset = 0;
2070 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2071 /*
2072 * AES-192 is an optional feature that may be unavailable when
2073 * there is an alternative underlying implementation i.e. when
2074 * MBEDTLS_AES_ALT is defined.
2075 */
2076 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2077 mbedtls_printf("skipped\n");
2078 continue;
2079 } else if (ret != 0) {
2080 goto exit;
2081 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002082
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002083 if (mode == MBEDTLS_AES_DECRYPT) {
2084 memcpy(buf, aes_test_cfb128_ct[u], 64);
2085 aes_tests = aes_test_cfb128_pt;
2086 } else {
2087 memcpy(buf, aes_test_cfb128_pt, 64);
2088 aes_tests = aes_test_cfb128_ct[u];
2089 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002091 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2092 if (ret != 0) {
2093 goto exit;
2094 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002095
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 if (memcmp(buf, aes_tests, 64) != 0) {
2097 ret = 1;
2098 goto exit;
2099 }
2100
2101 if (verbose != 0) {
2102 mbedtls_printf("passed\n");
2103 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002104 }
2105
Gilles Peskine449bd832023-01-11 14:50:10 +01002106 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002107 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002108 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002109 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002110#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002111
Simon Butcherad4e4932018-04-29 00:43:47 +01002112#if defined(MBEDTLS_CIPHER_MODE_OFB)
2113 /*
2114 * OFB mode
2115 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002116 {
2117 static const int num_tests =
2118 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002119
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002120 for (i = 0; i < num_tests << 1; i++) {
2121 u = i >> 1;
2122 keybits = 128 + u * 64;
2123 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002124
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002125 if (verbose != 0) {
2126 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2127 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2128 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002129
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002130 memcpy(iv, aes_test_ofb_iv, 16);
2131 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002132
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002133 offset = 0;
2134 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2135 /*
2136 * AES-192 is an optional feature that may be unavailable when
2137 * there is an alternative underlying implementation i.e. when
2138 * MBEDTLS_AES_ALT is defined.
2139 */
2140 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2141 mbedtls_printf("skipped\n");
2142 continue;
2143 } else if (ret != 0) {
2144 goto exit;
2145 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002146
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002147 if (mode == MBEDTLS_AES_DECRYPT) {
2148 memcpy(buf, aes_test_ofb_ct[u], 64);
2149 aes_tests = aes_test_ofb_pt;
2150 } else {
2151 memcpy(buf, aes_test_ofb_pt, 64);
2152 aes_tests = aes_test_ofb_ct[u];
2153 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002154
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002155 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2156 if (ret != 0) {
2157 goto exit;
2158 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002159
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002160 if (memcmp(buf, aes_tests, 64) != 0) {
2161 ret = 1;
2162 goto exit;
2163 }
2164
2165 if (verbose != 0) {
2166 mbedtls_printf("passed\n");
2167 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002168 }
2169
Gilles Peskine449bd832023-01-11 14:50:10 +01002170 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002171 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002172 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002173 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002174#endif /* MBEDTLS_CIPHER_MODE_OFB */
2175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002176#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002177 /*
2178 * CTR mode
2179 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002180 {
2181 static const int num_tests =
2182 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002183
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002184 for (i = 0; i < num_tests << 1; i++) {
2185 u = i >> 1;
2186 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002187
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002188 if (verbose != 0) {
2189 mbedtls_printf(" AES-CTR-128 (%s): ",
2190 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2191 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002192
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002193 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2194 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002195
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002196 offset = 0;
2197 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2198 goto exit;
2199 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002200
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002201 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002202
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002203 if (mode == MBEDTLS_AES_DECRYPT) {
2204 memcpy(buf, aes_test_ctr_ct[u], len);
2205 aes_tests = aes_test_ctr_pt[u];
2206 } else {
2207 memcpy(buf, aes_test_ctr_pt[u], len);
2208 aes_tests = aes_test_ctr_ct[u];
2209 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002210
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002211 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2212 stream_block, buf, buf);
2213 if (ret != 0) {
2214 goto exit;
2215 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002216
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002217 if (memcmp(buf, aes_tests, len) != 0) {
2218 ret = 1;
2219 goto exit;
2220 }
2221
2222 if (verbose != 0) {
2223 mbedtls_printf("passed\n");
2224 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002225 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002226 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002227
Gilles Peskine449bd832023-01-11 14:50:10 +01002228 if (verbose != 0) {
2229 mbedtls_printf("\n");
2230 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002231#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002232
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002233#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002234 /*
2235 * XTS mode
2236 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002237 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002238 static const int num_tests =
2239 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2240 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002241
Gilles Peskine449bd832023-01-11 14:50:10 +01002242 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002243
Gilles Peskine449bd832023-01-11 14:50:10 +01002244 for (i = 0; i < num_tests << 1; i++) {
2245 const unsigned char *data_unit;
2246 u = i >> 1;
2247 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002248
Gilles Peskine449bd832023-01-11 14:50:10 +01002249 if (verbose != 0) {
2250 mbedtls_printf(" AES-XTS-128 (%s): ",
2251 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2252 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002253
Gilles Peskine449bd832023-01-11 14:50:10 +01002254 memset(key, 0, sizeof(key));
2255 memcpy(key, aes_test_xts_key[u], 32);
2256 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002257
Gilles Peskine449bd832023-01-11 14:50:10 +01002258 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002259
Gilles Peskine449bd832023-01-11 14:50:10 +01002260 if (mode == MBEDTLS_AES_DECRYPT) {
2261 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2262 if (ret != 0) {
2263 goto exit;
2264 }
2265 memcpy(buf, aes_test_xts_ct32[u], len);
2266 aes_tests = aes_test_xts_pt32[u];
2267 } else {
2268 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2269 if (ret != 0) {
2270 goto exit;
2271 }
2272 memcpy(buf, aes_test_xts_pt32[u], len);
2273 aes_tests = aes_test_xts_ct32[u];
2274 }
2275
2276
2277 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2278 buf, buf);
2279 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002280 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002281 }
2282
2283 if (memcmp(buf, aes_tests, len) != 0) {
2284 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002285 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002286 }
2287
2288 if (verbose != 0) {
2289 mbedtls_printf("passed\n");
2290 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002291 }
2292
Gilles Peskine449bd832023-01-11 14:50:10 +01002293 if (verbose != 0) {
2294 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002295 }
2296
Gilles Peskine449bd832023-01-11 14:50:10 +01002297 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002298 }
2299#endif /* MBEDTLS_CIPHER_MODE_XTS */
2300
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002301 ret = 0;
2302
2303exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002304 if (ret != 0 && verbose != 0) {
2305 mbedtls_printf("failed\n");
2306 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002307
Gilles Peskine449bd832023-01-11 14:50:10 +01002308 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002309
Gilles Peskine449bd832023-01-11 14:50:10 +01002310 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002311}
2312
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002313#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002314
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002315#endif /* MBEDTLS_AES_C */