blob: b4b34232d1664132f79e716750c543d6b7ca1c5a [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
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000037#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000038#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000040#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010041#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080042#if defined(MBEDTLS_AESCE_C)
43#include "aesce.h"
44#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020048#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020049
Gilles Peskine0f454e42023-03-16 14:58:46 +010050#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000051static int aes_padlock_ace = -1;
52#endif
53
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000055/*
56 * Forward S-box
57 */
58static const unsigned char FSb[256] =
59{
60 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
61 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
62 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
63 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
64 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
65 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
66 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
67 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
68 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
69 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
70 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
71 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
72 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
73 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
74 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
75 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
76 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
77 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
78 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
79 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
80 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
81 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
82 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
83 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
84 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
85 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
86 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
87 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
88 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
89 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
90 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
91 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
92};
93
94/*
95 * Forward tables
96 */
97#define FT \
98\
Gilles Peskine449bd832023-01-11 14:50:10 +010099 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
100 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
101 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
102 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
103 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
104 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
105 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
106 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
107 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
108 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
109 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
110 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
111 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
112 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
113 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
114 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
115 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
116 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
117 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
118 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
119 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
120 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
121 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
122 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
123 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
124 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
125 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
126 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
127 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
128 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
129 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
130 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
131 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
132 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
133 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
134 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
135 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
136 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
137 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
138 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
139 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
140 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
141 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
142 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
143 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
144 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
145 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
146 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
147 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
148 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
149 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
150 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
151 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
152 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
153 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
154 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
155 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
156 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
157 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
158 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
159 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
160 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
161 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
162 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 +0000163
Gilles Peskine449bd832023-01-11 14:50:10 +0100164#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000165static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000166#undef V
167
Hanno Beckerad049a92017-06-19 16:31:54 +0100168#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200169
Gilles Peskine449bd832023-01-11 14:50:10 +0100170#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000171static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000172#undef V
173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000175static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000176#undef V
177
Gilles Peskine449bd832023-01-11 14:50:10 +0100178#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000179static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000180#undef V
181
Hanno Becker177d3cf2017-06-07 15:52:48 +0100182#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200183
Paul Bakker5121ce52009-01-03 21:22:43 +0000184#undef FT
185
186/*
187 * Reverse S-box
188 */
189static const unsigned char RSb[256] =
190{
191 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
192 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
193 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
194 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
195 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
196 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
197 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
198 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
199 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
200 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
201 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
202 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
203 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
204 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
205 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
206 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
207 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
208 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
209 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
210 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
211 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
212 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
213 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
214 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
215 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
216 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
217 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
218 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
219 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
220 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
221 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
222 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
223};
224
225/*
226 * Reverse tables
227 */
228#define RT \
229\
Gilles Peskine449bd832023-01-11 14:50:10 +0100230 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
231 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
232 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
233 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
234 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
235 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
236 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
237 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
238 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
239 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
240 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
241 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
242 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
243 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
244 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
245 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
246 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
247 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
248 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
249 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
250 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
251 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
252 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
253 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
254 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
255 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
256 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
257 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
258 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
259 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
260 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
261 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
262 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
263 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
264 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
265 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
266 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
267 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
268 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
269 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
270 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
271 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
272 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
273 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
274 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
275 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
276 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
277 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
278 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
279 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
280 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
281 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
282 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
283 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
284 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
285 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
286 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
287 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
288 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
289 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
290 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
291 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
292 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
293 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 +0000294
Gilles Peskine449bd832023-01-11 14:50:10 +0100295#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000296static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000297#undef V
298
Hanno Beckerad049a92017-06-19 16:31:54 +0100299#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000302static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000303#undef V
304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000306static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000307#undef V
308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000310static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000311#undef V
312
Hanno Becker177d3cf2017-06-07 15:52:48 +0100313#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200314
Paul Bakker5121ce52009-01-03 21:22:43 +0000315#undef RT
316
317/*
318 * Round constants
319 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000320static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000321{
322 0x00000001, 0x00000002, 0x00000004, 0x00000008,
323 0x00000010, 0x00000020, 0x00000040, 0x00000080,
324 0x0000001B, 0x00000036
325};
326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000328
329/*
330 * Forward S-box & tables
331 */
332static unsigned char FSb[256];
Paul Bakker9af723c2014-05-01 13:03:14 +0200333static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100334#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200335static uint32_t FT1[256];
336static uint32_t FT2[256];
337static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100338#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
340/*
341 * Reverse S-box & tables
342 */
343static unsigned char RSb[256];
Paul Bakker5c2364c2012-10-01 14:41:15 +0000344static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100345#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346static uint32_t RT1[256];
347static uint32_t RT2[256];
348static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100349#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351/*
352 * Round constants
353 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000354static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000355
356/*
357 * Tables generation code
358 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100359#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
360#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
361#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
363static int aes_init_done = 0;
364
Gilles Peskine449bd832023-01-11 14:50:10 +0100365static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000366{
367 int i, x, y, z;
368 int pow[256];
369 int log[256];
370
371 /*
372 * compute pow and log tables over GF(2^8)
373 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000375 pow[i] = x;
376 log[x] = i;
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 x = MBEDTLS_BYTE_0(x ^ XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000378 }
379
380 /*
381 * calculate the round constants
382 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100383 for (i = 0, x = 1; i < 10; i++) {
Paul Bakker5c2364c2012-10-01 14:41:15 +0000384 RCON[i] = (uint32_t) x;
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 x = MBEDTLS_BYTE_0(XTIME(x));
Paul Bakker5121ce52009-01-03 21:22:43 +0000386 }
387
388 /*
389 * generate the forward and reverse S-boxes
390 */
391 FSb[0x00] = 0x63;
392 RSb[0x63] = 0x00;
393
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 x = pow[255 - log[i]];
396
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 y = x; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
398 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
399 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
400 x ^= y; y = MBEDTLS_BYTE_0((y << 1) | (y >> 7));
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 x ^= y ^ 0x63;
402
403 FSb[i] = (unsigned char) x;
404 RSb[x] = (unsigned char) i;
405 }
406
407 /*
408 * generate the forward and reverse tables
409 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 x = FSb[i];
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 y = MBEDTLS_BYTE_0(XTIME(x));
413 z = MBEDTLS_BYTE_0(y ^ x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 FT0[i] = ((uint32_t) y) ^
416 ((uint32_t) x << 8) ^
417 ((uint32_t) x << 16) ^
418 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
Hanno Beckerad049a92017-06-19 16:31:54 +0100420#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 FT1[i] = ROTL8(FT0[i]);
422 FT2[i] = ROTL8(FT1[i]);
423 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100424#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
426 x = RSb[i];
427
Gilles Peskine449bd832023-01-11 14:50:10 +0100428 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
429 ((uint32_t) MUL(0x09, x) << 8) ^
430 ((uint32_t) MUL(0x0D, x) << 16) ^
431 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
Hanno Beckerad049a92017-06-19 16:31:54 +0100433#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 RT1[i] = ROTL8(RT0[i]);
435 RT2[i] = ROTL8(RT1[i]);
436 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100437#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 }
439}
440
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200441#undef ROTL8
442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
Hanno Beckerad049a92017-06-19 16:31:54 +0100445#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200446
Gilles Peskine449bd832023-01-11 14:50:10 +0100447#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
448#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
449#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200450
451#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100452#define AES_RT1(idx) ROTL8(RT0[idx])
453#define AES_RT2(idx) ROTL16(RT0[idx])
454#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200455
456#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100457#define AES_FT1(idx) ROTL8(FT0[idx])
458#define AES_FT2(idx) ROTL16(FT0[idx])
459#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200460
Hanno Becker177d3cf2017-06-07 15:52:48 +0100461#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200462
463#define AES_RT0(idx) RT0[idx]
464#define AES_RT1(idx) RT1[idx]
465#define AES_RT2(idx) RT2[idx]
466#define AES_RT3(idx) RT3[idx]
467
468#define AES_FT0(idx) FT0[idx]
469#define AES_FT1(idx) FT1[idx]
470#define AES_FT2(idx) FT2[idx]
471#define AES_FT3(idx) FT3[idx]
472
Hanno Becker177d3cf2017-06-07 15:52:48 +0100473#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200474
Gilles Peskine449bd832023-01-11 14:50:10 +0100475void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200476{
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200478}
479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200481{
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200483 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200485
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200487}
488
Jaeden Amero9366feb2018-05-29 18:55:17 +0100489#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100490void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100491{
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 mbedtls_aes_init(&ctx->crypt);
493 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100494}
495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100497{
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100499 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 }
Simon Butcher5201e412018-12-06 17:40:14 +0000501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 mbedtls_aes_free(&ctx->crypt);
503 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100504}
505#endif /* MBEDTLS_CIPHER_MODE_XTS */
506
Paul Bakker5121ce52009-01-03 21:22:43 +0000507/*
508 * AES key schedule (encryption)
509 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200510#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100511int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
512 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000513{
Paul Bakker23986e52011-04-24 08:57:21 +0000514 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000515 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000516
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 case 128: ctx->nr = 10; break;
519 case 192: ctx->nr = 12; break;
520 case 256: ctx->nr = 14; break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 }
523
Simon Butcher5201e412018-12-06 17:40:14 +0000524#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000526 aes_gen_tables();
527 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000528 }
529#endif
530
Werner Lewis7656a372022-06-13 12:28:20 +0100531 ctx->rk_offset = 0;
Gilles Peskine0f454e42023-03-16 14:58:46 +0100532#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 if (aes_padlock_ace == -1) {
534 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
535 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 if (aes_padlock_ace) {
538 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
539 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000540#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100541 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000542
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100543#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100544 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Gilles Peskined6719172023-03-10 22:37:11 +0100545 /* The intrinsics-based implementation needs 16-byte alignment
546 * for the round key array. */
547 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
548 if (delta != 0) {
549 ctx->rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
550 }
551 RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100552 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
553 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100554#endif
555
Jerry Yu3f2fb712023-01-10 17:05:42 +0800556#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
557 if (mbedtls_aesce_has_support()) {
558 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
559 }
560#endif
561
Gilles Peskine449bd832023-01-11 14:50:10 +0100562 for (i = 0; i < (keybits >> 5); i++) {
563 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000564 }
565
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000567 case 10:
568
Gilles Peskine449bd832023-01-11 14:50:10 +0100569 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100571 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
572 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
573 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
574 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 RK[5] = RK[1] ^ RK[4];
577 RK[6] = RK[2] ^ RK[5];
578 RK[7] = RK[3] ^ RK[6];
579 }
580 break;
581
582 case 12:
583
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000585 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
587 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
588 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
589 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000590
591 RK[7] = RK[1] ^ RK[6];
592 RK[8] = RK[2] ^ RK[7];
593 RK[9] = RK[3] ^ RK[8];
594 RK[10] = RK[4] ^ RK[9];
595 RK[11] = RK[5] ^ RK[10];
596 }
597 break;
598
599 case 14:
600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
604 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
605 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
606 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000607
608 RK[9] = RK[1] ^ RK[8];
609 RK[10] = RK[2] ^ RK[9];
610 RK[11] = RK[3] ^ RK[10];
611
612 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
614 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
615 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
616 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000617
618 RK[13] = RK[5] ^ RK[12];
619 RK[14] = RK[6] ^ RK[13];
620 RK[15] = RK[7] ^ RK[14];
621 }
622 break;
Paul Bakker5121ce52009-01-03 21:22:43 +0000623 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000624
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000626}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200627#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000628
629/*
630 * AES key schedule (decryption)
631 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200632#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100633int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
634 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000635{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200636 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000638 uint32_t *RK;
639 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200640
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000642
Werner Lewis7656a372022-06-13 12:28:20 +0100643 ctx->rk_offset = 0;
Gilles Peskine0f454e42023-03-16 14:58:46 +0100644#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +0100645 if (aes_padlock_ace == -1) {
646 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
647 }
Paul Bakker048d04e2012-02-12 17:31:04 +0000648
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 if (aes_padlock_ace) {
650 ctx->rk_offset = MBEDTLS_PADLOCK_ALIGN16(ctx->buf) - ctx->buf;
651 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000652#endif
Gilles Peskined6719172023-03-10 22:37:11 +0100653#if defined(MBEDTLS_AESNI_HAVE_CODE)
654 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
655 /* The intrinsics-based implementation needs 16-byte alignment
656 * for the round key array. */
657 unsigned delta = (uintptr_t) ctx->buf & 0x0000000f;
658 if (delta != 0) {
659 ctx->rk_offset = 4 - delta / 4; // 16 bytes = 4 uint32_t
660 }
661 }
662#endif
Werner Lewisdd76ef32022-05-30 12:00:21 +0100663 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000664
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200665 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200667 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000669
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200670 ctx->nr = cty.nr;
671
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100672#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100673 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
674 mbedtls_aesni_inverse_key((unsigned char *) RK,
675 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200676 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100677 }
678#endif
679
Jerry Yue096da12023-01-10 17:07:01 +0800680#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
681 if (mbedtls_aesce_has_support()) {
682 mbedtls_aesce_inverse_key(
683 (unsigned char *) RK,
684 (const unsigned char *) (cty.buf + cty.rk_offset),
685 ctx->nr);
686 goto exit;
687 }
688#endif
689
Werner Lewisdd76ef32022-05-30 12:00:21 +0100690 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
692 *RK++ = *SK++;
693 *RK++ = *SK++;
694 *RK++ = *SK++;
695 *RK++ = *SK++;
696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
698 for (j = 0; j < 4; j++, SK++) {
699 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
700 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
701 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
702 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 }
704 }
705
706 *RK++ = *SK++;
707 *RK++ = *SK++;
708 *RK++ = *SK++;
709 *RK++ = *SK++;
710
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200711exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000713
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000715}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100716#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100717
718#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100719static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
720 unsigned int keybits,
721 const unsigned char **key1,
722 unsigned int *key1bits,
723 const unsigned char **key2,
724 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100725{
726 const unsigned int half_keybits = keybits / 2;
727 const unsigned int half_keybytes = half_keybits / 8;
728
Gilles Peskine449bd832023-01-11 14:50:10 +0100729 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100730 case 256: break;
731 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100733 }
734
735 *key1bits = half_keybits;
736 *key2bits = half_keybits;
737 *key1 = &key[0];
738 *key2 = &key[half_keybytes];
739
740 return 0;
741}
742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
744 const unsigned char *key,
745 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100746{
Janos Follath24eed8d2019-11-22 13:21:35 +0000747 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100748 const unsigned char *key1, *key2;
749 unsigned int key1bits, key2bits;
750
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
752 &key2, &key2bits);
753 if (ret != 0) {
754 return ret;
755 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100756
757 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
759 if (ret != 0) {
760 return ret;
761 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100762
763 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100765}
766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
768 const unsigned char *key,
769 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100770{
Janos Follath24eed8d2019-11-22 13:21:35 +0000771 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100772 const unsigned char *key1, *key2;
773 unsigned int key1bits, key2bits;
774
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
776 &key2, &key2bits);
777 if (ret != 0) {
778 return ret;
779 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100780
781 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
783 if (ret != 0) {
784 return ret;
785 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100786
787 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100789}
790#endif /* MBEDTLS_CIPHER_MODE_XTS */
791
Gilles Peskine449bd832023-01-11 14:50:10 +0100792#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100793 do \
794 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100795 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
796 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
797 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
798 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100799 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
801 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
802 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
803 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100804 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100805 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
806 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
807 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
808 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100809 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
811 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
812 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
813 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
814 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000815
Gilles Peskine449bd832023-01-11 14:50:10 +0100816#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100817 do \
818 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
820 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
821 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
822 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100823 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100824 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
825 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
826 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
827 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100828 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
830 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
831 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
832 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100833 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100834 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
835 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
836 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
837 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
838 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000839
840/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200841 * AES-ECB block encryption
842 */
843#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100844int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
845 const unsigned char input[16],
846 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200847{
848 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100849 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200851 uint32_t X[4];
852 uint32_t Y[4];
853 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
856 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
857 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
858 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200859
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
861 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]);
862 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 +0200863 }
864
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 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 +0200866
Gilles Peskine5197c662020-08-26 17:03:24 +0200867 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100868 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
869 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
870 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
871 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200872
Gilles Peskine5197c662020-08-26 17:03:24 +0200873 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100874 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
875 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
876 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
877 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200878
Gilles Peskine5197c662020-08-26 17:03:24 +0200879 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
881 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
882 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
883 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200884
Gilles Peskine5197c662020-08-26 17:03:24 +0200885 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100886 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
887 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
888 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
889 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200890
Gilles Peskine449bd832023-01-11 14:50:10 +0100891 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
892 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
893 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
894 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500897
Gilles Peskine449bd832023-01-11 14:50:10 +0100898 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200899}
900#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
901
902/*
903 * AES-ECB block decryption
904 */
905#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100906int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
907 const unsigned char input[16],
908 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200909{
910 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100911 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100912 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200913 uint32_t X[4];
914 uint32_t Y[4];
915 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200916
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
918 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
919 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
920 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
923 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]);
924 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 +0200925 }
926
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 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 +0200928
Gilles Peskine5197c662020-08-26 17:03:24 +0200929 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
931 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
932 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
933 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200934
Gilles Peskine5197c662020-08-26 17:03:24 +0200935 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100936 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
937 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
938 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
939 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200940
Gilles Peskine5197c662020-08-26 17:03:24 +0200941 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
943 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
944 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
945 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200946
Gilles Peskine5197c662020-08-26 17:03:24 +0200947 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100948 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
949 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
950 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
951 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
954 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
955 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
956 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200961}
962#endif /* !MBEDTLS_AES_DECRYPT_ALT */
963
Gilles Peskine148cad12023-03-16 13:08:42 +0100964#if defined(MBEDTLS_AESNI_HAVE_CODE) || \
965 (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86))
966/* VIA Padlock and our intrinsics-based implementation of AESNI require
967 * the round keys to be aligned on a 16-byte boundary. We take care of this
968 * before creating them, but the AES context may have moved (this can happen
969 * if the library is called from a language with managed memory), and in later
970 * calls it might have a different alignment with respect to 16-byte memory.
971 * So we may need to realign.
972 */
973static void aes_maybe_realign(mbedtls_aes_context *ctx)
974{
975 /* We want a 16-byte alignment. Note that buf is a pointer to uint32_t
976 * and rk_offset is in units of uint32_t words = 4 bytes. We want a
977 * 4-word alignment. */
978 uintptr_t current_address = (uintptr_t) (ctx->buf + ctx->rk_offset);
979 unsigned current_alignment = (current_address & 0x0000000f) / 4;
980 if (current_alignment != 0) {
981 unsigned new_offset = ctx->rk_offset + 4 - current_alignment;
982 if (new_offset >= 4) {
983 new_offset -= 4;
984 }
985 memmove(ctx->buf + new_offset, // new address
986 ctx->buf + ctx->rk_offset, // current address
987 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
988 ctx->rk_offset = new_offset;
989 }
990}
991#endif
992
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200993/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000994 * AES-ECB block encryption/decryption
995 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100996int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
997 int mode,
998 const unsigned char input[16],
999 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001000{
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001002 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001003 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001004
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001005#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001007 aes_maybe_realign(ctx);
Gilles Peskine449bd832023-01-11 14:50:10 +01001008 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1009 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001010#endif
1011
Jerry Yu2bb3d812023-01-10 17:38:26 +08001012#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1013 if (mbedtls_aesce_has_support()) {
1014 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1015 }
1016#endif
1017
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001018#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001020 aes_maybe_realign(ctx);
1021 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001022 }
1023#endif
1024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 if (mode == MBEDTLS_AES_ENCRYPT) {
1026 return mbedtls_internal_aes_encrypt(ctx, input, output);
1027 } else {
1028 return mbedtls_internal_aes_decrypt(ctx, input, output);
1029 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001030}
1031
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001033/*
1034 * AES-CBC buffer encryption/decryption
1035 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001036int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1037 int mode,
1038 size_t length,
1039 unsigned char iv[16],
1040 const unsigned char *input,
1041 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001042{
Gilles Peskine7820a572021-07-07 21:08:28 +02001043 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001044 unsigned char temp[16];
1045
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001047 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001049
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 if (length % 16) {
1051 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1052 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001053
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001054#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 if (aes_padlock_ace > 0) {
1056 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1057 return 0;
1058 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001059
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001060 // If padlock data misaligned, we just fall back to
1061 // unaccelerated mode
1062 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001063 }
1064#endif
1065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (mode == MBEDTLS_AES_DECRYPT) {
1067 while (length > 0) {
1068 memcpy(temp, input, 16);
1069 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1070 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001071 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001072 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 mbedtls_xor(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001075
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001077
1078 input += 16;
1079 output += 16;
1080 length -= 16;
1081 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 } else {
1083 while (length > 0) {
1084 mbedtls_xor(output, input, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1087 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001088 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 }
1090 memcpy(iv, output, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001091
1092 input += 16;
1093 output += 16;
1094 length -= 16;
1095 }
1096 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001097 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001098
Gilles Peskine7820a572021-07-07 21:08:28 +02001099exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001100 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001101}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001102#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001103
Aorimn5f778012016-06-09 23:22:58 +02001104#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001105
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001106typedef unsigned char mbedtls_be128[16];
1107
1108/*
1109 * GF(2^128) multiplication function
1110 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001111 * This function multiplies a field element by x in the polynomial field
1112 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001113 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001114 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001115 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001116static void mbedtls_gf128mul_x_ble(unsigned char r[16],
1117 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001118{
1119 uint64_t a, b, ra, rb;
1120
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 a = MBEDTLS_GET_UINT64_LE(x, 0);
1122 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001123
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1125 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001126
Gilles Peskine449bd832023-01-11 14:50:10 +01001127 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1128 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001129}
1130
Aorimn5f778012016-06-09 23:22:58 +02001131/*
1132 * AES-XTS buffer encryption/decryption
1133 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001134int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1135 int mode,
1136 size_t length,
1137 const unsigned char data_unit[16],
1138 const unsigned char *input,
1139 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001140{
Janos Follath24eed8d2019-11-22 13:21:35 +00001141 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001142 size_t blocks = length / 16;
1143 size_t leftover = length % 16;
1144 unsigned char tweak[16];
1145 unsigned char prev_tweak[16];
1146 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001147
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001149 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001150 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001151
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001152 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001153 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001154 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 }
Aorimn5f778012016-06-09 23:22:58 +02001156
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001157 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001159 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 }
Aorimn5f778012016-06-09 23:22:58 +02001161
Jaeden Amerod82cd862018-04-28 15:02:45 +01001162 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001163 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1164 data_unit, tweak);
1165 if (ret != 0) {
1166 return ret;
1167 }
Aorimn5f778012016-06-09 23:22:58 +02001168
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 while (blocks--) {
1170 if (leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001171 /* We are on the last block in a decrypt operation that has
1172 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001173 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001174 * the leftovers and then update the current tweak for use on this,
1175 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 memcpy(prev_tweak, tweak, sizeof(tweak));
1177 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001178 }
1179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001181
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1183 if (ret != 0) {
1184 return ret;
1185 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001186
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001188
1189 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001191
1192 output += 16;
1193 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001194 }
1195
Gilles Peskine449bd832023-01-11 14:50:10 +01001196 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001197 /* If we are on the leftover bytes in a decrypt operation, we need to
1198 * use the previous tweak for these bytes (as saved in prev_tweak). */
1199 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001200
Jaeden Amerod82cd862018-04-28 15:02:45 +01001201 /* We are now on the final part of the data unit, which doesn't divide
1202 * evenly by 16. It's time for ciphertext stealing. */
1203 size_t i;
1204 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001205
Jaeden Amerod82cd862018-04-28 15:02:45 +01001206 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001207 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001209 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001210 }
Aorimn5f778012016-06-09 23:22:58 +02001211
Dave Rodgman069e7f42022-11-24 19:37:26 +00001212 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001214
Jaeden Amerod82cd862018-04-28 15:02:45 +01001215 /* Copy ciphertext bytes from the previous block for input in this
1216 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001218
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1220 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001221 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 }
Aorimn5f778012016-06-09 23:22:58 +02001223
Jaeden Amerod82cd862018-04-28 15:02:45 +01001224 /* Write the result back to the previous block, overriding the previous
1225 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001227 }
1228
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001230}
1231#endif /* MBEDTLS_CIPHER_MODE_XTS */
1232
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001233#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001234/*
1235 * AES-CFB128 buffer encryption/decryption
1236 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001237int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1238 int mode,
1239 size_t length,
1240 size_t *iv_off,
1241 unsigned char iv[16],
1242 const unsigned char *input,
1243 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001244{
Paul Bakker27fdf462011-06-09 13:55:13 +00001245 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001246 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001247 size_t n;
1248
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001250 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001252
1253 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001254
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 if (n > 15) {
1256 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1257 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001258
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 if (mode == MBEDTLS_AES_DECRYPT) {
1260 while (length--) {
1261 if (n == 0) {
1262 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1263 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001264 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001266 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001267
1268 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001270 iv[n] = (unsigned char) c;
1271
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001273 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 } else {
1275 while (length--) {
1276 if (n == 0) {
1277 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1278 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001279 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001281 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001282
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001284
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001286 }
1287 }
1288
1289 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001290 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001291
Gilles Peskine7820a572021-07-07 21:08:28 +02001292exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001293 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001294}
Paul Bakker556efba2014-01-24 15:38:12 +01001295
1296/*
1297 * AES-CFB8 buffer encryption/decryption
1298 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001299int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1300 int mode,
1301 size_t length,
1302 unsigned char iv[16],
1303 const unsigned char *input,
1304 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001305{
Gilles Peskine7820a572021-07-07 21:08:28 +02001306 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001307 unsigned char c;
1308 unsigned char ov[17];
1309
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001311 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 }
1313 while (length--) {
1314 memcpy(ov, iv, 16);
1315 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1316 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001317 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 }
Paul Bakker556efba2014-01-24 15:38:12 +01001319
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001321 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 }
Paul Bakker556efba2014-01-24 15:38:12 +01001323
Gilles Peskine449bd832023-01-11 14:50:10 +01001324 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001325
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001327 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 }
Paul Bakker556efba2014-01-24 15:38:12 +01001329
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001331 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001332 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001333
Gilles Peskine7820a572021-07-07 21:08:28 +02001334exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001336}
Simon Butcher76a5b222018-04-22 22:57:27 +01001337#endif /* MBEDTLS_CIPHER_MODE_CFB */
1338
1339#if defined(MBEDTLS_CIPHER_MODE_OFB)
1340/*
1341 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1342 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001343int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1344 size_t length,
1345 size_t *iv_off,
1346 unsigned char iv[16],
1347 const unsigned char *input,
1348 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001349{
Simon Butcherad4e4932018-04-29 00:43:47 +01001350 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001351 size_t n;
1352
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001353 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001354
Gilles Peskine449bd832023-01-11 14:50:10 +01001355 if (n > 15) {
1356 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1357 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001358
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 while (length--) {
1360 if (n == 0) {
1361 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1362 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001363 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001365 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001366 *output++ = *input++ ^ iv[n];
1367
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001369 }
1370
1371 *iv_off = n;
1372
Simon Butcherad4e4932018-04-29 00:43:47 +01001373exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001375}
1376#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001377
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001378#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001379/*
1380 * AES-CTR buffer encryption/decryption
1381 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001382int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1383 size_t length,
1384 size_t *nc_off,
1385 unsigned char nonce_counter[16],
1386 unsigned char stream_block[16],
1387 const unsigned char *input,
1388 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001389{
Paul Bakker369e14b2012-04-18 14:16:09 +00001390 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001391 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001392 size_t n;
1393
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001394 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001395
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 if (n > 0x0F) {
1397 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1398 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001399
Gilles Peskine449bd832023-01-11 14:50:10 +01001400 while (length--) {
1401 if (n == 0) {
1402 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1403 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001404 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001405 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001406
Gilles Peskine449bd832023-01-11 14:50:10 +01001407 for (i = 16; i > 0; i--) {
1408 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001409 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 }
1411 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001412 }
1413 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001415
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001417 }
1418
1419 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001420 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001421
Gilles Peskine7820a572021-07-07 21:08:28 +02001422exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001423 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001424}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001425#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001426
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001427#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001430/*
1431 * AES test vectors from:
1432 *
1433 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1434 */
1435static const unsigned char aes_test_ecb_dec[3][16] =
1436{
1437 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1438 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
1439 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1440 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1441 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1442 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
1443};
1444
1445static const unsigned char aes_test_ecb_enc[3][16] =
1446{
1447 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1448 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
1449 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1450 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1451 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1452 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
1453};
1454
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001455#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001456static const unsigned char aes_test_cbc_dec[3][16] =
1457{
1458 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1459 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
1460 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1461 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1462 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1463 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
1464};
1465
1466static const unsigned char aes_test_cbc_enc[3][16] =
1467{
1468 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1469 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
1470 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1471 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1472 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1473 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
1474};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001475#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001477#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001478/*
1479 * AES-CFB128 test vectors from:
1480 *
1481 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1482 */
1483static const unsigned char aes_test_cfb128_key[3][32] =
1484{
1485 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1486 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1487 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1488 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1489 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1490 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1491 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1492 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1493 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1494};
1495
1496static const unsigned char aes_test_cfb128_iv[16] =
1497{
1498 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1499 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1500};
1501
1502static const unsigned char aes_test_cfb128_pt[64] =
1503{
1504 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1505 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1506 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1507 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1508 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1509 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1510 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1511 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1512};
1513
1514static const unsigned char aes_test_cfb128_ct[3][64] =
1515{
1516 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1517 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1518 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1519 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1520 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1521 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1522 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1523 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
1524 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1525 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1526 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1527 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1528 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1529 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1530 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1531 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1532 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1533 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1534 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1535 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1536 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1537 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1538 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1539 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
1540};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001541#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001542
Simon Butcherad4e4932018-04-29 00:43:47 +01001543#if defined(MBEDTLS_CIPHER_MODE_OFB)
1544/*
1545 * AES-OFB test vectors from:
1546 *
Simon Butcher5db13622018-06-04 22:11:25 +01001547 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001548 */
1549static const unsigned char aes_test_ofb_key[3][32] =
1550{
1551 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1552 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
1553 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1554 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1555 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1556 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1557 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1558 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1559 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
1560};
1561
1562static const unsigned char aes_test_ofb_iv[16] =
1563{
1564 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1565 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1566};
1567
1568static const unsigned char aes_test_ofb_pt[64] =
1569{
1570 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1571 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1572 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1573 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1574 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1575 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1576 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1577 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1578};
1579
1580static const unsigned char aes_test_ofb_ct[3][64] =
1581{
1582 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1583 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1584 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1585 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1586 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1587 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1588 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1589 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
1590 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1591 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1592 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1593 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1594 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1595 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1596 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1597 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1598 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1599 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1600 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1601 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1602 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1603 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1604 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1605 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
1606};
1607#endif /* MBEDTLS_CIPHER_MODE_OFB */
1608
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001609#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001610/*
1611 * AES-CTR test vectors from:
1612 *
1613 * http://www.faqs.org/rfcs/rfc3686.html
1614 */
1615
1616static const unsigned char aes_test_ctr_key[3][16] =
1617{
1618 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1619 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1620 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1621 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1622 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1623 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1624};
1625
1626static const unsigned char aes_test_ctr_nonce_counter[3][16] =
1627{
1628 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1630 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1631 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1632 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1633 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1634};
1635
1636static const unsigned char aes_test_ctr_pt[3][48] =
1637{
1638 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1639 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
1640
1641 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1642 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1643 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1644 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1645
1646 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1647 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1648 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1649 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1650 0x20, 0x21, 0x22, 0x23 }
1651};
1652
1653static const unsigned char aes_test_ctr_ct[3][48] =
1654{
1655 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1656 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1657 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1658 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1659 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1660 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1661 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1662 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1663 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1664 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1665 0x25, 0xB2, 0x07, 0x2F }
1666};
1667
1668static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001669{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001670#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001671
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001672#if defined(MBEDTLS_CIPHER_MODE_XTS)
1673/*
1674 * AES-XTS test vectors from:
1675 *
1676 * IEEE P1619/D16 Annex B
1677 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1678 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1679 */
1680static const unsigned char aes_test_xts_key[][32] =
1681{
1682 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1686 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1687 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1688 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1689 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1690 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1691 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1692 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1693 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1694};
1695
1696static const unsigned char aes_test_xts_pt32[][32] =
1697{
1698 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1702 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1703 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1704 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1705 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1706 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1707 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1708 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1709 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1710};
1711
1712static const unsigned char aes_test_xts_ct32[][32] =
1713{
1714 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1715 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1716 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1717 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1718 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1719 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1720 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1721 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1722 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1723 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1724 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1725 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1726};
1727
1728static const unsigned char aes_test_xts_data_unit[][16] =
1729{
Gilles Peskine449bd832023-01-11 14:50:10 +01001730 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1732 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1734 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001736};
1737
1738#endif /* MBEDTLS_CIPHER_MODE_XTS */
1739
Paul Bakker5121ce52009-01-03 21:22:43 +00001740/*
1741 * Checkup routine
1742 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001743int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001744{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001745 int ret = 0, i, j, u, mode;
1746 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001747 unsigned char key[32];
1748 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001749 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001750#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1751 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001752 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001753#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001754#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001755 unsigned char prv[16];
1756#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001757#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1758 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001759 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001760#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001761#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001762 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001763#endif
1764#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001765 unsigned char nonce_counter[16];
1766 unsigned char stream_block[16];
1767#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001768 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001769
Gilles Peskine449bd832023-01-11 14:50:10 +01001770 memset(key, 0, 32);
1771 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001772
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001773 if (verbose != 0) {
1774#if defined(MBEDTLS_AES_ALT)
1775 mbedtls_printf(" AES note: alternative implementation.\n");
1776#else /* MBEDTLS_AES_ALT */
1777#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1778 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1779 mbedtls_printf(" AES note: using VIA Padlock.\n");
1780 } else
1781#endif
1782#if defined(MBEDTLS_AESNI_HAVE_CODE)
1783 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1784 mbedtls_printf(" AES note: using AESNI.\n");
1785 } else
1786#endif
1787#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1788 if (mbedtls_aesce_has_support()) {
1789 mbedtls_printf(" AES note: using AESCE.\n");
1790 } else
1791#endif
1792 mbedtls_printf(" AES note: built-in implementation.\n");
1793#endif /* MBEDTLS_AES_ALT */
1794 }
1795
Paul Bakker5121ce52009-01-03 21:22:43 +00001796 /*
1797 * ECB mode
1798 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001799 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001800 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001801 keybits = 128 + u * 64;
1802 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001803
Gilles Peskine449bd832023-01-11 14:50:10 +01001804 if (verbose != 0) {
1805 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1806 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001807 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001808
1809 memset(buf, 0, 16);
1810
1811 if (mode == MBEDTLS_AES_DECRYPT) {
1812 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1813 aes_tests = aes_test_ecb_dec[u];
1814 } else {
1815 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001816 aes_tests = aes_test_ecb_enc[u];
1817 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001818
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001819 /*
1820 * AES-192 is an optional feature that may be unavailable when
1821 * there is an alternative underlying implementation i.e. when
1822 * MBEDTLS_AES_ALT is defined.
1823 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001824 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1825 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001826 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001827 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001828 goto exit;
1829 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001830
Gilles Peskine449bd832023-01-11 14:50:10 +01001831 for (j = 0; j < 10000; j++) {
1832 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1833 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001834 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001835 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001836 }
1837
Gilles Peskine449bd832023-01-11 14:50:10 +01001838 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001839 ret = 1;
1840 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001841 }
1842
Gilles Peskine449bd832023-01-11 14:50:10 +01001843 if (verbose != 0) {
1844 mbedtls_printf("passed\n");
1845 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001846 }
1847
Gilles Peskine449bd832023-01-11 14:50:10 +01001848 if (verbose != 0) {
1849 mbedtls_printf("\n");
1850 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001851
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001852#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001853 /*
1854 * CBC mode
1855 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001856 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001857 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001858 keybits = 128 + u * 64;
1859 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001860
Gilles Peskine449bd832023-01-11 14:50:10 +01001861 if (verbose != 0) {
1862 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1863 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001864 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001865
1866 memset(iv, 0, 16);
1867 memset(prv, 0, 16);
1868 memset(buf, 0, 16);
1869
1870 if (mode == MBEDTLS_AES_DECRYPT) {
1871 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1872 aes_tests = aes_test_cbc_dec[u];
1873 } else {
1874 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001875 aes_tests = aes_test_cbc_enc[u];
1876 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001877
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001878 /*
1879 * AES-192 is an optional feature that may be unavailable when
1880 * there is an alternative underlying implementation i.e. when
1881 * MBEDTLS_AES_ALT is defined.
1882 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001883 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1884 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001885 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001886 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001887 goto exit;
1888 }
1889
Gilles Peskine449bd832023-01-11 14:50:10 +01001890 for (j = 0; j < 10000; j++) {
1891 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001892 unsigned char tmp[16];
1893
Gilles Peskine449bd832023-01-11 14:50:10 +01001894 memcpy(tmp, prv, 16);
1895 memcpy(prv, buf, 16);
1896 memcpy(buf, tmp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001897 }
1898
Gilles Peskine449bd832023-01-11 14:50:10 +01001899 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1900 if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001901 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001902 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001903
1904 }
1905
Gilles Peskine449bd832023-01-11 14:50:10 +01001906 if (memcmp(buf, aes_tests, 16) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001907 ret = 1;
1908 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001909 }
1910
Gilles Peskine449bd832023-01-11 14:50:10 +01001911 if (verbose != 0) {
1912 mbedtls_printf("passed\n");
1913 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001914 }
1915
Gilles Peskine449bd832023-01-11 14:50:10 +01001916 if (verbose != 0) {
1917 mbedtls_printf("\n");
1918 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001920
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001921#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001922 /*
1923 * CFB128 mode
1924 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001925 for (i = 0; i < 6; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +00001926 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001927 keybits = 128 + u * 64;
1928 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001929
Gilles Peskine449bd832023-01-11 14:50:10 +01001930 if (verbose != 0) {
1931 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
1932 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1933 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001934
Gilles Peskine449bd832023-01-11 14:50:10 +01001935 memcpy(iv, aes_test_cfb128_iv, 16);
1936 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00001937
1938 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001939 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Andres Amaya Garciad3e7e7d2017-06-15 16:17:46 +01001940 /*
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 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001945 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1946 mbedtls_printf("skipped\n");
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001947 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01001948 } else if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001949 goto exit;
1950 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001951
Gilles Peskine449bd832023-01-11 14:50:10 +01001952 if (mode == MBEDTLS_AES_DECRYPT) {
1953 memcpy(buf, aes_test_cfb128_ct[u], 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001954 aes_tests = aes_test_cfb128_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01001955 } else {
1956 memcpy(buf, aes_test_cfb128_pt, 64);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001957 aes_tests = aes_test_cfb128_ct[u];
1958 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001959
Gilles Peskine449bd832023-01-11 14:50:10 +01001960 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
1961 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001962 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001963 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001964
Gilles Peskine449bd832023-01-11 14:50:10 +01001965 if (memcmp(buf, aes_tests, 64) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001966 ret = 1;
1967 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +00001968 }
1969
Gilles Peskine449bd832023-01-11 14:50:10 +01001970 if (verbose != 0) {
1971 mbedtls_printf("passed\n");
1972 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001973 }
1974
Gilles Peskine449bd832023-01-11 14:50:10 +01001975 if (verbose != 0) {
1976 mbedtls_printf("\n");
1977 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001978#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001979
Simon Butcherad4e4932018-04-29 00:43:47 +01001980#if defined(MBEDTLS_CIPHER_MODE_OFB)
1981 /*
1982 * OFB mode
1983 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001984 for (i = 0; i < 6; i++) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001985 u = i >> 1;
1986 keybits = 128 + u * 64;
1987 mode = i & 1;
1988
Gilles Peskine449bd832023-01-11 14:50:10 +01001989 if (verbose != 0) {
1990 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
1991 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1992 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001993
Gilles Peskine449bd832023-01-11 14:50:10 +01001994 memcpy(iv, aes_test_ofb_iv, 16);
1995 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01001996
1997 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001998 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
Simon Butcherad4e4932018-04-29 00:43:47 +01001999 /*
2000 * AES-192 is an optional feature that may be unavailable when
2001 * there is an alternative underlying implementation i.e. when
2002 * MBEDTLS_AES_ALT is defined.
2003 */
Gilles Peskine449bd832023-01-11 14:50:10 +01002004 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2005 mbedtls_printf("skipped\n");
Simon Butcherad4e4932018-04-29 00:43:47 +01002006 continue;
Gilles Peskine449bd832023-01-11 14:50:10 +01002007 } else if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002008 goto exit;
2009 }
2010
Gilles Peskine449bd832023-01-11 14:50:10 +01002011 if (mode == MBEDTLS_AES_DECRYPT) {
2012 memcpy(buf, aes_test_ofb_ct[u], 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002013 aes_tests = aes_test_ofb_pt;
Gilles Peskine449bd832023-01-11 14:50:10 +01002014 } else {
2015 memcpy(buf, aes_test_ofb_pt, 64);
Simon Butcherad4e4932018-04-29 00:43:47 +01002016 aes_tests = aes_test_ofb_ct[u];
2017 }
2018
Gilles Peskine449bd832023-01-11 14:50:10 +01002019 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2020 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002021 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002022 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002023
Gilles Peskine449bd832023-01-11 14:50:10 +01002024 if (memcmp(buf, aes_tests, 64) != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01002025 ret = 1;
2026 goto exit;
2027 }
2028
Gilles Peskine449bd832023-01-11 14:50:10 +01002029 if (verbose != 0) {
2030 mbedtls_printf("passed\n");
2031 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002032 }
2033
Gilles Peskine449bd832023-01-11 14:50:10 +01002034 if (verbose != 0) {
2035 mbedtls_printf("\n");
2036 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002037#endif /* MBEDTLS_CIPHER_MODE_OFB */
2038
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002039#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002040 /*
2041 * CTR mode
2042 */
Gilles Peskine449bd832023-01-11 14:50:10 +01002043 for (i = 0; i < 6; i++) {
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002044 u = i >> 1;
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002045 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002046
Gilles Peskine449bd832023-01-11 14:50:10 +01002047 if (verbose != 0) {
2048 mbedtls_printf(" AES-CTR-128 (%s): ",
2049 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2050 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002051
Gilles Peskine449bd832023-01-11 14:50:10 +01002052 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2053 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002054
2055 offset = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01002056 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002057 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002058 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002059
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002060 len = aes_test_ctr_len[u];
2061
Gilles Peskine449bd832023-01-11 14:50:10 +01002062 if (mode == MBEDTLS_AES_DECRYPT) {
2063 memcpy(buf, aes_test_ctr_ct[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002064 aes_tests = aes_test_ctr_pt[u];
Gilles Peskine449bd832023-01-11 14:50:10 +01002065 } else {
2066 memcpy(buf, aes_test_ctr_pt[u], len);
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002067 aes_tests = aes_test_ctr_ct[u];
2068 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002069
Gilles Peskine449bd832023-01-11 14:50:10 +01002070 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2071 stream_block, buf, buf);
2072 if (ret != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002073 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002074 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002075
Gilles Peskine449bd832023-01-11 14:50:10 +01002076 if (memcmp(buf, aes_tests, len) != 0) {
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002077 ret = 1;
2078 goto exit;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002079 }
2080
Gilles Peskine449bd832023-01-11 14:50:10 +01002081 if (verbose != 0) {
2082 mbedtls_printf("passed\n");
2083 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002084 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002085
Gilles Peskine449bd832023-01-11 14:50:10 +01002086 if (verbose != 0) {
2087 mbedtls_printf("\n");
2088 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002089#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002091#if defined(MBEDTLS_CIPHER_MODE_XTS)
2092 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002093 static const int num_tests =
2094 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2095 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002096
Gilles Peskine449bd832023-01-11 14:50:10 +01002097 /*
2098 * XTS mode
2099 */
2100 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002101
Gilles Peskine449bd832023-01-11 14:50:10 +01002102 for (i = 0; i < num_tests << 1; i++) {
2103 const unsigned char *data_unit;
2104 u = i >> 1;
2105 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002106
Gilles Peskine449bd832023-01-11 14:50:10 +01002107 if (verbose != 0) {
2108 mbedtls_printf(" AES-XTS-128 (%s): ",
2109 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2110 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002111
Gilles Peskine449bd832023-01-11 14:50:10 +01002112 memset(key, 0, sizeof(key));
2113 memcpy(key, aes_test_xts_key[u], 32);
2114 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002115
Gilles Peskine449bd832023-01-11 14:50:10 +01002116 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002117
Gilles Peskine449bd832023-01-11 14:50:10 +01002118 if (mode == MBEDTLS_AES_DECRYPT) {
2119 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2120 if (ret != 0) {
2121 goto exit;
2122 }
2123 memcpy(buf, aes_test_xts_ct32[u], len);
2124 aes_tests = aes_test_xts_pt32[u];
2125 } else {
2126 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2127 if (ret != 0) {
2128 goto exit;
2129 }
2130 memcpy(buf, aes_test_xts_pt32[u], len);
2131 aes_tests = aes_test_xts_ct32[u];
2132 }
2133
2134
2135 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2136 buf, buf);
2137 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002138 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002139 }
2140
2141 if (memcmp(buf, aes_tests, len) != 0) {
2142 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002143 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002144 }
2145
2146 if (verbose != 0) {
2147 mbedtls_printf("passed\n");
2148 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002149 }
2150
Gilles Peskine449bd832023-01-11 14:50:10 +01002151 if (verbose != 0) {
2152 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002153 }
2154
Gilles Peskine449bd832023-01-11 14:50:10 +01002155 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002156 }
2157#endif /* MBEDTLS_CIPHER_MODE_XTS */
2158
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002159 ret = 0;
2160
2161exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002162 if (ret != 0 && verbose != 0) {
2163 mbedtls_printf("failed\n");
2164 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002165
Gilles Peskine449bd832023-01-11 14:50:10 +01002166 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002167
Gilles Peskine449bd832023-01-11 14:50:10 +01002168 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002169}
2170
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002171#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002173#endif /* MBEDTLS_AES_C */