blob: fa773ec601bfe4cc8411392cb41e50152131e6f7 [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 *
Tom Cosgrovece37c5e2023-08-04 13:53:36 +010022 * https://csrc.nist.gov/csrc/media/projects/cryptographic-standards-and-guidelines/documents/aes-development/rijndael-ammended.pdf
Paul Bakker5121ce52009-01-03 21:22:43 +000023 * 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 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010058#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
59 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000060static const unsigned char FSb[256] =
61{
62 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
63 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
64 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
65 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
66 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
67 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
68 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
69 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
70 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
71 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
72 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
73 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
74 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
75 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
76 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
77 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
78 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
79 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
80 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
81 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
82 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
83 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
84 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
85 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
86 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
87 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
88 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
89 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
90 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
91 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
92 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
93 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
94};
Dave Rodgmanafe85db2023-06-29 12:07:11 +010095#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
96 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +000097
98/*
99 * Forward tables
100 */
101#define FT \
102\
Gilles Peskine449bd832023-01-11 14:50:10 +0100103 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
104 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
105 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
106 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
107 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
108 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
109 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
110 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
111 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
112 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
113 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
114 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
115 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
116 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
117 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
118 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
119 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
120 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
121 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
122 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
123 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
124 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
125 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
126 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
127 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
128 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
129 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
130 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
131 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
132 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
133 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
134 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
135 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
136 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
137 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
138 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
139 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
140 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
141 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
142 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
143 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
144 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
145 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
146 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
147 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
148 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
149 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
150 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
151 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
152 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
153 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
154 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
155 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
156 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
157 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
158 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
159 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
160 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
161 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
162 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
163 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
164 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
165 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
166 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 +0000167
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100168#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100169#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000170static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000171#undef V
172
Hanno Beckerad049a92017-06-19 16:31:54 +0100173#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200174
Gilles Peskine449bd832023-01-11 14:50:10 +0100175#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000176static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000177#undef V
178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000180static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000181#undef V
182
Gilles Peskine449bd832023-01-11 14:50:10 +0100183#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000184static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000185#undef V
186
Hanno Becker177d3cf2017-06-07 15:52:48 +0100187#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200188
Dave Rodgman1be24632023-06-29 12:01:24 +0100189#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
190
Paul Bakker5121ce52009-01-03 21:22:43 +0000191#undef FT
192
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100193#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000194/*
195 * Reverse S-box
196 */
197static const unsigned char RSb[256] =
198{
199 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
200 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
201 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
202 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
203 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
204 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
205 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
206 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
207 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
208 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
209 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
210 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
211 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
212 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
213 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
214 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
215 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
216 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
217 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
218 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
219 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
220 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
221 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
222 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
223 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
224 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
225 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
226 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
227 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
228 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
229 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
230 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
231};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100232#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
234/*
235 * Reverse tables
236 */
237#define RT \
238\
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
240 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
241 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
242 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
243 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
244 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
245 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
246 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
247 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
248 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
249 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
250 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
251 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
252 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
253 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
254 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
255 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
256 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
257 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
258 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
259 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
260 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
261 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
262 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
263 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
264 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
265 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
266 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
267 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
268 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
269 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
270 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
271 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
272 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
273 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
274 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
275 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
276 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
277 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
278 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
279 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
280 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
281 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
282 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
283 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
284 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
285 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
286 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
287 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
288 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
289 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
290 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
291 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
292 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
293 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
294 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
295 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
296 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
297 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
298 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
299 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
300 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
301 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
302 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 +0000303
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100304#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
305
Gilles Peskine449bd832023-01-11 14:50:10 +0100306#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000308#undef V
309
Hanno Beckerad049a92017-06-19 16:31:54 +0100310#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000313static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000314#undef V
315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000317static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000318#undef V
319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000321static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000322#undef V
323
Hanno Becker177d3cf2017-06-07 15:52:48 +0100324#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200325
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800326#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
327
Paul Bakker5121ce52009-01-03 21:22:43 +0000328#undef RT
329
Dave Rodgman34152a42023-06-27 18:31:24 +0100330#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000331/*
332 * Round constants
333 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000334static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000335{
336 0x00000001, 0x00000002, 0x00000004, 0x00000008,
337 0x00000010, 0x00000020, 0x00000040, 0x00000080,
338 0x0000001B, 0x00000036
339};
Dave Rodgman34152a42023-06-27 18:31:24 +0100340#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344/*
345 * Forward S-box & tables
346 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100347#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
348 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000349static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100350#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
351 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100352#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200353static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100354#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200355static uint32_t FT1[256];
356static uint32_t FT2[256];
357static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100358#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100359#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
361/*
362 * Reverse S-box & tables
363 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100364#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000365static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100366#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100367
368#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000369static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100370#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000371static uint32_t RT1[256];
372static uint32_t RT2[256];
373static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100374#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100375#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
Dave Rodgman8c753f92023-06-27 18:16:13 +0100377#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000378/*
379 * Round constants
380 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000381static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000382
383/*
384 * Tables generation code
385 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100386#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
387#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
388#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
390static int aes_init_done = 0;
391
Gilles Peskine449bd832023-01-11 14:50:10 +0100392static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000393{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800394 int i;
395 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800396 uint8_t pow[256];
397 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
399 /*
400 * compute pow and log tables over GF(2^8)
401 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800404 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800405 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 }
407
408 /*
409 * calculate the round constants
410 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800412 RCON[i] = x;
413 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 }
415
416 /*
417 * generate the forward and reverse S-boxes
418 */
419 FSb[0x00] = 0x63;
420 RSb[0x63] = 0x00;
421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 x = pow[255 - log[i]];
424
Yanray Wangfe944ce2023-06-26 18:16:01 +0800425 y = x; y = (y << 1) | (y >> 7);
426 x ^= y; y = (y << 1) | (y >> 7);
427 x ^= y; y = (y << 1) | (y >> 7);
428 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 x ^= y ^ 0x63;
430
Yanray Wangfe944ce2023-06-26 18:16:01 +0800431 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 RSb[x] = (unsigned char) i;
433 }
434
435 /*
436 * generate the forward and reverse tables
437 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800440 y = XTIME(x);
441 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 FT0[i] = ((uint32_t) y) ^
444 ((uint32_t) x << 8) ^
445 ((uint32_t) x << 16) ^
446 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
Hanno Beckerad049a92017-06-19 16:31:54 +0100448#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100449 FT1[i] = ROTL8(FT0[i]);
450 FT2[i] = ROTL8(FT1[i]);
451 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100452#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
454 x = RSb[i];
455
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100456#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
458 ((uint32_t) MUL(0x09, x) << 8) ^
459 ((uint32_t) MUL(0x0D, x) << 16) ^
460 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
Hanno Beckerad049a92017-06-19 16:31:54 +0100462#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 RT1[i] = ROTL8(RT0[i]);
464 RT2[i] = ROTL8(RT1[i]);
465 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100466#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100467#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 }
469}
470
Dave Rodgman8c753f92023-06-27 18:16:13 +0100471#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
472
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200473#undef ROTL8
474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
Hanno Beckerad049a92017-06-19 16:31:54 +0100477#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
480#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
481#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200482
483#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100484#define AES_RT1(idx) ROTL8(RT0[idx])
485#define AES_RT2(idx) ROTL16(RT0[idx])
486#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200487
488#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100489#define AES_FT1(idx) ROTL8(FT0[idx])
490#define AES_FT2(idx) ROTL16(FT0[idx])
491#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200492
Hanno Becker177d3cf2017-06-07 15:52:48 +0100493#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200494
495#define AES_RT0(idx) RT0[idx]
496#define AES_RT1(idx) RT1[idx]
497#define AES_RT2(idx) RT2[idx]
498#define AES_RT3(idx) RT3[idx]
499
500#define AES_FT0(idx) FT0[idx]
501#define AES_FT1(idx) FT1[idx]
502#define AES_FT2(idx) FT2[idx]
503#define AES_FT3(idx) FT3[idx]
504
Hanno Becker177d3cf2017-06-07 15:52:48 +0100505#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200506
Gilles Peskine449bd832023-01-11 14:50:10 +0100507void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200508{
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200510}
511
Gilles Peskine449bd832023-01-11 14:50:10 +0100512void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200513{
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200515 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100516 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200517
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200519}
520
Jaeden Amero9366feb2018-05-29 18:55:17 +0100521#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100522void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100523{
Gilles Peskine449bd832023-01-11 14:50:10 +0100524 mbedtls_aes_init(&ctx->crypt);
525 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100526}
527
Gilles Peskine449bd832023-01-11 14:50:10 +0100528void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100529{
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100531 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 }
Simon Butcher5201e412018-12-06 17:40:14 +0000533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 mbedtls_aes_free(&ctx->crypt);
535 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100536}
537#endif /* MBEDTLS_CIPHER_MODE_XTS */
538
Gilles Peskine0de8f852023-03-16 17:14:59 +0100539/* Some implementations need the round keys to be aligned.
540 * Return an offset to be added to buf, such that (buf + offset) is
541 * correctly aligned.
542 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
543 * i.e. an offset of 1 means 4 bytes and so on.
544 */
545#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100546 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100547#define MAY_NEED_TO_ALIGN
548#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100549
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100550#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
551 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100552static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
553{
554#if defined(MAY_NEED_TO_ALIGN)
555 int align_16_bytes = 0;
556
557#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
558 if (aes_padlock_ace == -1) {
559 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
560 }
561 if (aes_padlock_ace) {
562 align_16_bytes = 1;
563 }
564#endif
565
Gilles Peskine9c682e72023-03-16 17:21:33 +0100566#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100567 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
568 align_16_bytes = 1;
569 }
570#endif
571
572 if (align_16_bytes) {
573 /* These implementations needs 16-byte alignment
574 * for the round key array. */
575 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
576 if (delta == 0) {
577 return 0;
578 } else {
579 return 4 - delta; // 16 bytes = 4 uint32_t
580 }
581 }
582#else /* MAY_NEED_TO_ALIGN */
583 (void) buf;
584#endif /* MAY_NEED_TO_ALIGN */
585
586 return 0;
587}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100588#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
589 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100590
Paul Bakker5121ce52009-01-03 21:22:43 +0000591/*
592 * AES key schedule (encryption)
593 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200594#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100595int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
596 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000597{
Paul Bakker23986e52011-04-24 08:57:21 +0000598 unsigned int i;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000599 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600
Gilles Peskine449bd832023-01-11 14:50:10 +0100601 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800603#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000604 case 192: ctx->nr = 12; break;
605 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800606#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 }
609
Simon Butcher5201e412018-12-06 17:40:14 +0000610#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000612 aes_gen_tables();
613 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000614 }
615#endif
616
Gilles Peskine0de8f852023-03-16 17:14:59 +0100617 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100618 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000619
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100620#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100621 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
622 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
623 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100624#endif
625
Jerry Yu3f2fb712023-01-10 17:05:42 +0800626#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
627 if (mbedtls_aesce_has_support()) {
628 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
629 }
630#endif
631
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 for (i = 0; i < (keybits >> 5); i++) {
633 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000637 case 10:
638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
642 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
643 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
644 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000645
646 RK[5] = RK[1] ^ RK[4];
647 RK[6] = RK[2] ^ RK[5];
648 RK[7] = RK[3] ^ RK[6];
649 }
650 break;
651
Arto Kinnunen732ca322023-04-14 14:26:10 +0800652#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 case 12:
654
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000656 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
658 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
659 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
660 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662 RK[7] = RK[1] ^ RK[6];
663 RK[8] = RK[2] ^ RK[7];
664 RK[9] = RK[3] ^ RK[8];
665 RK[10] = RK[4] ^ RK[9];
666 RK[11] = RK[5] ^ RK[10];
667 }
668 break;
669
670 case 14:
671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000673 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
675 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
676 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
677 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
679 RK[9] = RK[1] ^ RK[8];
680 RK[10] = RK[2] ^ RK[9];
681 RK[11] = RK[3] ^ RK[10];
682
683 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
685 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
687 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
689 RK[13] = RK[5] ^ RK[12];
690 RK[14] = RK[6] ^ RK[13];
691 RK[15] = RK[7] ^ RK[14];
692 }
693 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800694#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000698}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200699#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701/*
702 * AES key schedule (decryption)
703 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200704#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100705int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
706 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000707{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200708 int i, j, ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000710 uint32_t *RK;
711 uint32_t *SK;
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200712
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000714
Gilles Peskine0de8f852023-03-16 17:14:59 +0100715 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100716 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000717
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200718 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100719 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200720 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100721 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000722
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200723 ctx->nr = cty.nr;
724
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100725#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
727 mbedtls_aesni_inverse_key((unsigned char *) RK,
728 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200729 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100730 }
731#endif
732
Jerry Yue096da12023-01-10 17:07:01 +0800733#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
734 if (mbedtls_aesce_has_support()) {
735 mbedtls_aesce_inverse_key(
736 (unsigned char *) RK,
737 (const unsigned char *) (cty.buf + cty.rk_offset),
738 ctx->nr);
739 goto exit;
740 }
741#endif
742
Werner Lewisdd76ef32022-05-30 12:00:21 +0100743 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000744
745 *RK++ = *SK++;
746 *RK++ = *SK++;
747 *RK++ = *SK++;
748 *RK++ = *SK++;
749
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
751 for (j = 0; j < 4; j++, SK++) {
752 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
753 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
754 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
755 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000756 }
757 }
758
759 *RK++ = *SK++;
760 *RK++ = *SK++;
761 *RK++ = *SK++;
762 *RK++ = *SK++;
763
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200764exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000766
Gilles Peskine449bd832023-01-11 14:50:10 +0100767 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000768}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100769#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100770
771#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100772static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
773 unsigned int keybits,
774 const unsigned char **key1,
775 unsigned int *key1bits,
776 const unsigned char **key2,
777 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100778{
779 const unsigned int half_keybits = keybits / 2;
780 const unsigned int half_keybytes = half_keybits / 8;
781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100783 case 256: break;
784 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100786 }
787
788 *key1bits = half_keybits;
789 *key2bits = half_keybits;
790 *key1 = &key[0];
791 *key2 = &key[half_keybytes];
792
793 return 0;
794}
795
Gilles Peskine449bd832023-01-11 14:50:10 +0100796int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
797 const unsigned char *key,
798 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100799{
Janos Follath24eed8d2019-11-22 13:21:35 +0000800 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100801 const unsigned char *key1, *key2;
802 unsigned int key1bits, key2bits;
803
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
805 &key2, &key2bits);
806 if (ret != 0) {
807 return ret;
808 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100809
810 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
812 if (ret != 0) {
813 return ret;
814 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100815
816 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818}
819
Gilles Peskine449bd832023-01-11 14:50:10 +0100820int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
821 const unsigned char *key,
822 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100823{
Janos Follath24eed8d2019-11-22 13:21:35 +0000824 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100825 const unsigned char *key1, *key2;
826 unsigned int key1bits, key2bits;
827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
829 &key2, &key2bits);
830 if (ret != 0) {
831 return ret;
832 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100833
834 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100835 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
836 if (ret != 0) {
837 return ret;
838 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100839
840 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100842}
843#endif /* MBEDTLS_CIPHER_MODE_XTS */
844
Gilles Peskine449bd832023-01-11 14:50:10 +0100845#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100846 do \
847 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
849 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
850 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
851 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100852 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
854 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
855 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
856 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100857 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
859 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
860 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
861 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100862 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100863 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
864 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
865 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
866 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
867 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000868
Gilles Peskine449bd832023-01-11 14:50:10 +0100869#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100870 do \
871 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
873 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
874 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
875 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100876 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100877 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
878 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
879 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
880 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100881 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100882 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
883 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
884 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
885 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100886 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100887 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
888 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
889 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
890 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
891 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000892
893/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200894 * AES-ECB block encryption
895 */
896#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100897int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
898 const unsigned char input[16],
899 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200900{
901 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100902 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100903 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200904 uint32_t X[4];
905 uint32_t Y[4];
906 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
909 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
910 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
911 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200912
Gilles Peskine449bd832023-01-11 14:50:10 +0100913 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
914 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]);
915 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 +0200916 }
917
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 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 +0200919
Gilles Peskine5197c662020-08-26 17:03:24 +0200920 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
922 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
923 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
924 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200925
Gilles Peskine5197c662020-08-26 17:03:24 +0200926 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100927 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
928 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
929 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
930 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200931
Gilles Peskine5197c662020-08-26 17:03:24 +0200932 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
934 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
935 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
936 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200937
Gilles Peskine5197c662020-08-26 17:03:24 +0200938 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100939 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
940 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
941 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
942 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200943
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
945 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
946 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
947 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500950
Gilles Peskine449bd832023-01-11 14:50:10 +0100951 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200952}
953#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
954
955/*
956 * AES-ECB block decryption
957 */
958#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100959int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
960 const unsigned char input[16],
961 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200962{
963 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100964 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200966 uint32_t X[4];
967 uint32_t Y[4];
968 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200969
Gilles Peskine449bd832023-01-11 14:50:10 +0100970 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
971 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
972 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
973 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200974
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
976 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]);
977 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 +0200978 }
979
Gilles Peskine449bd832023-01-11 14:50:10 +0100980 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 +0200981
Gilles Peskine5197c662020-08-26 17:03:24 +0200982 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
984 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
985 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
986 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200987
Gilles Peskine5197c662020-08-26 17:03:24 +0200988 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100989 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
990 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
991 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
992 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200993
Gilles Peskine5197c662020-08-26 17:03:24 +0200994 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100995 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
996 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
997 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
998 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200999
Gilles Peskine5197c662020-08-26 17:03:24 +02001000 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1002 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1003 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1004 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001005
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1007 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1008 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1009 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001010
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001012
Gilles Peskine449bd832023-01-11 14:50:10 +01001013 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001014}
1015#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1016
Gilles Peskine0de8f852023-03-16 17:14:59 +01001017#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001018/* VIA Padlock and our intrinsics-based implementation of AESNI require
1019 * the round keys to be aligned on a 16-byte boundary. We take care of this
1020 * before creating them, but the AES context may have moved (this can happen
1021 * if the library is called from a language with managed memory), and in later
1022 * calls it might have a different alignment with respect to 16-byte memory.
1023 * So we may need to realign.
1024 */
1025static void aes_maybe_realign(mbedtls_aes_context *ctx)
1026{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001027 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1028 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001029 memmove(ctx->buf + new_offset, // new address
1030 ctx->buf + ctx->rk_offset, // current address
1031 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1032 ctx->rk_offset = new_offset;
1033 }
1034}
1035#endif
1036
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001037/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 * AES-ECB block encryption/decryption
1039 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001040int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1041 int mode,
1042 const unsigned char input[16],
1043 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001044{
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001046 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001048
Gilles Peskine0de8f852023-03-16 17:14:59 +01001049#if defined(MAY_NEED_TO_ALIGN)
1050 aes_maybe_realign(ctx);
1051#endif
1052
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001053#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1055 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1056 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001057#endif
1058
Jerry Yu2bb3d812023-01-10 17:38:26 +08001059#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1060 if (mbedtls_aesce_has_support()) {
1061 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1062 }
1063#endif
1064
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001067 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001068 }
1069#endif
1070
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 if (mode == MBEDTLS_AES_ENCRYPT) {
1072 return mbedtls_internal_aes_encrypt(ctx, input, output);
1073 } else {
1074 return mbedtls_internal_aes_decrypt(ctx, input, output);
1075 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001076}
1077
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001079
Paul Bakker5121ce52009-01-03 21:22:43 +00001080/*
1081 * AES-CBC buffer encryption/decryption
1082 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001083int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1084 int mode,
1085 size_t length,
1086 unsigned char iv[16],
1087 const unsigned char *input,
1088 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001089{
Gilles Peskine7820a572021-07-07 21:08:28 +02001090 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001091 unsigned char temp[16];
1092
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001094 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001096
Paul Elliott2ad93672023-08-11 11:07:06 +01001097 /* Nothing to do if length is zero. */
1098 if (length == 0) {
1099 return 0;
1100 }
1101
Gilles Peskine449bd832023-01-11 14:50:10 +01001102 if (length % 16) {
1103 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1104 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001106#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 if (aes_padlock_ace > 0) {
1108 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1109 return 0;
1110 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001111
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001112 // If padlock data misaligned, we just fall back to
1113 // unaccelerated mode
1114 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001115 }
1116#endif
1117
Dave Rodgman906c63c2023-06-14 17:53:51 +01001118 const unsigned char *ivp = iv;
1119
Gilles Peskine449bd832023-01-11 14:50:10 +01001120 if (mode == MBEDTLS_AES_DECRYPT) {
1121 while (length > 0) {
1122 memcpy(temp, input, 16);
1123 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1124 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001125 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001126 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001127 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001128 * the result for the next block in CBC, and the cost of transferring that data from
1129 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001130 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001131
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001133
1134 input += 16;
1135 output += 16;
1136 length -= 16;
1137 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 } else {
1139 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001140 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1143 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001144 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001145 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001146 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001147
1148 input += 16;
1149 output += 16;
1150 length -= 16;
1151 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001152 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001153 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001154 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001155
Gilles Peskine7820a572021-07-07 21:08:28 +02001156exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001158}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001160
Aorimn5f778012016-06-09 23:22:58 +02001161#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001162
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001163typedef unsigned char mbedtls_be128[16];
1164
1165/*
1166 * GF(2^128) multiplication function
1167 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001168 * This function multiplies a field element by x in the polynomial field
1169 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001170 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001171 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001172 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001173#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001174MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001175#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001176static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001177 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001178{
1179 uint64_t a, b, ra, rb;
1180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 a = MBEDTLS_GET_UINT64_LE(x, 0);
1182 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001183
Gilles Peskine449bd832023-01-11 14:50:10 +01001184 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1185 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001186
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1188 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001189}
1190
Aorimn5f778012016-06-09 23:22:58 +02001191/*
1192 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001193 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001194 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001195 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001196 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001197#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001198MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001199#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001200int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1201 int mode,
1202 size_t length,
1203 const unsigned char data_unit[16],
1204 const unsigned char *input,
1205 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001206{
Janos Follath24eed8d2019-11-22 13:21:35 +00001207 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001208 size_t blocks = length / 16;
1209 size_t leftover = length % 16;
1210 unsigned char tweak[16];
1211 unsigned char prev_tweak[16];
1212 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001213
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001215 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001216 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001217
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001218 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001220 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 }
Aorimn5f778012016-06-09 23:22:58 +02001222
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001223 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001224 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001225 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 }
Aorimn5f778012016-06-09 23:22:58 +02001227
Jaeden Amerod82cd862018-04-28 15:02:45 +01001228 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1230 data_unit, tweak);
1231 if (ret != 0) {
1232 return ret;
1233 }
Aorimn5f778012016-06-09 23:22:58 +02001234
Gilles Peskine449bd832023-01-11 14:50:10 +01001235 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001236 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001237 /* We are on the last block in a decrypt operation that has
1238 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001239 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001240 * the leftovers and then update the current tweak for use on this,
1241 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 memcpy(prev_tweak, tweak, sizeof(tweak));
1243 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001244 }
1245
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001247
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1249 if (ret != 0) {
1250 return ret;
1251 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001252
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001254
1255 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001257
1258 output += 16;
1259 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001260 }
1261
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001263 /* If we are on the leftover bytes in a decrypt operation, we need to
1264 * use the previous tweak for these bytes (as saved in prev_tweak). */
1265 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001266
Jaeden Amerod82cd862018-04-28 15:02:45 +01001267 /* We are now on the final part of the data unit, which doesn't divide
1268 * evenly by 16. It's time for ciphertext stealing. */
1269 size_t i;
1270 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001271
Jaeden Amerod82cd862018-04-28 15:02:45 +01001272 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001273 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001275 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001276 }
Aorimn5f778012016-06-09 23:22:58 +02001277
Dave Rodgman069e7f42022-11-24 19:37:26 +00001278 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001280
Jaeden Amerod82cd862018-04-28 15:02:45 +01001281 /* Copy ciphertext bytes from the previous block for input in this
1282 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001284
Gilles Peskine449bd832023-01-11 14:50:10 +01001285 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1286 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001287 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001288 }
Aorimn5f778012016-06-09 23:22:58 +02001289
Jaeden Amerod82cd862018-04-28 15:02:45 +01001290 /* Write the result back to the previous block, overriding the previous
1291 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001293 }
1294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001296}
1297#endif /* MBEDTLS_CIPHER_MODE_XTS */
1298
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001299#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001300/*
1301 * AES-CFB128 buffer encryption/decryption
1302 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001303int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1304 int mode,
1305 size_t length,
1306 size_t *iv_off,
1307 unsigned char iv[16],
1308 const unsigned char *input,
1309 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001310{
Paul Bakker27fdf462011-06-09 13:55:13 +00001311 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001312 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001313 size_t n;
1314
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001316 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001318
1319 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001320
Gilles Peskine449bd832023-01-11 14:50:10 +01001321 if (n > 15) {
1322 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1323 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001324
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 if (mode == MBEDTLS_AES_DECRYPT) {
1326 while (length--) {
1327 if (n == 0) {
1328 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1329 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001330 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001332 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001333
1334 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 iv[n] = (unsigned char) c;
1337
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001339 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 } else {
1341 while (length--) {
1342 if (n == 0) {
1343 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1344 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001345 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001347 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001350
Gilles Peskine449bd832023-01-11 14:50:10 +01001351 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001352 }
1353 }
1354
1355 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001356 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001357
Gilles Peskine7820a572021-07-07 21:08:28 +02001358exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001360}
Paul Bakker556efba2014-01-24 15:38:12 +01001361
1362/*
1363 * AES-CFB8 buffer encryption/decryption
1364 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001365int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1366 int mode,
1367 size_t length,
1368 unsigned char iv[16],
1369 const unsigned char *input,
1370 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001371{
Gilles Peskine7820a572021-07-07 21:08:28 +02001372 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001373 unsigned char c;
1374 unsigned char ov[17];
1375
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001377 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 }
1379 while (length--) {
1380 memcpy(ov, iv, 16);
1381 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1382 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001383 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001384 }
Paul Bakker556efba2014-01-24 15:38:12 +01001385
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001387 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 }
Paul Bakker556efba2014-01-24 15:38:12 +01001389
Gilles Peskine449bd832023-01-11 14:50:10 +01001390 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001391
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001393 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001394 }
Paul Bakker556efba2014-01-24 15:38:12 +01001395
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001397 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001398 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001399
Gilles Peskine7820a572021-07-07 21:08:28 +02001400exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001401 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001402}
Simon Butcher76a5b222018-04-22 22:57:27 +01001403#endif /* MBEDTLS_CIPHER_MODE_CFB */
1404
1405#if defined(MBEDTLS_CIPHER_MODE_OFB)
1406/*
1407 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1408 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001409int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1410 size_t length,
1411 size_t *iv_off,
1412 unsigned char iv[16],
1413 const unsigned char *input,
1414 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001415{
Simon Butcherad4e4932018-04-29 00:43:47 +01001416 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001417 size_t n;
1418
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001419 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001420
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 if (n > 15) {
1422 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1423 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001424
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 while (length--) {
1426 if (n == 0) {
1427 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1428 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001429 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001430 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001431 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001432 *output++ = *input++ ^ iv[n];
1433
Gilles Peskine449bd832023-01-11 14:50:10 +01001434 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001435 }
1436
1437 *iv_off = n;
1438
Simon Butcherad4e4932018-04-29 00:43:47 +01001439exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001440 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001441}
1442#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001444#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001445/*
1446 * AES-CTR buffer encryption/decryption
1447 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001448int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1449 size_t length,
1450 size_t *nc_off,
1451 unsigned char nonce_counter[16],
1452 unsigned char stream_block[16],
1453 const unsigned char *input,
1454 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001455{
Paul Bakker369e14b2012-04-18 14:16:09 +00001456 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001457 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001458 size_t n;
1459
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001460 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001461
Gilles Peskine449bd832023-01-11 14:50:10 +01001462 if (n > 0x0F) {
1463 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1464 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001465
Gilles Peskine449bd832023-01-11 14:50:10 +01001466 while (length--) {
1467 if (n == 0) {
1468 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1469 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001470 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001471 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001472
Gilles Peskine449bd832023-01-11 14:50:10 +01001473 for (i = 16; i > 0; i--) {
1474 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001475 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001476 }
1477 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001478 }
1479 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001480 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001481
Gilles Peskine449bd832023-01-11 14:50:10 +01001482 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001483 }
1484
1485 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001486 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001487
Gilles Peskine7820a572021-07-07 21:08:28 +02001488exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001489 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001490}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001491#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001496/*
1497 * AES test vectors from:
1498 *
1499 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1500 */
Yanray Wang62c99912023-05-11 11:06:53 +08001501static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001502{
1503 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1504 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001505#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001506 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1507 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1508 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1509 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001510#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001511};
1512
Yanray Wang62c99912023-05-11 11:06:53 +08001513static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001514{
1515 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1516 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001517#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001518 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1519 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1520 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1521 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001522#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001523};
1524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001526static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001527{
1528 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1529 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001530#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001531 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1532 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1533 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1534 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001535#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001536};
1537
Yanray Wang62c99912023-05-11 11:06:53 +08001538static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001539{
1540 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1541 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001542#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001543 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1544 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1545 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1546 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001547#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001548};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001549#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001550
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001551#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001552/*
1553 * AES-CFB128 test vectors from:
1554 *
1555 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1556 */
Yanray Wang62c99912023-05-11 11:06:53 +08001557static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001558{
1559 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1560 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001561#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001562 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1563 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1564 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1565 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1566 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1567 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1568 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001569#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001570};
1571
1572static const unsigned char aes_test_cfb128_iv[16] =
1573{
1574 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1575 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1576};
1577
1578static const unsigned char aes_test_cfb128_pt[64] =
1579{
1580 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1581 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1582 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1583 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1584 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1585 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1586 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1587 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1588};
1589
Yanray Wang62c99912023-05-11 11:06:53 +08001590static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001591{
1592 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1593 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1594 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1595 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1596 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1597 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1598 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1599 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001600#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001601 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1602 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1603 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1604 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1605 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1606 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1607 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1608 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1609 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1610 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1611 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1612 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1613 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1614 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1615 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1616 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001617#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001618};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001619#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001620
Simon Butcherad4e4932018-04-29 00:43:47 +01001621#if defined(MBEDTLS_CIPHER_MODE_OFB)
1622/*
1623 * AES-OFB test vectors from:
1624 *
Simon Butcher5db13622018-06-04 22:11:25 +01001625 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001626 */
Yanray Wang62c99912023-05-11 11:06:53 +08001627static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001628{
1629 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1630 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001631#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001632 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1633 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1634 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1635 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1636 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1637 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1638 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001639#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001640};
1641
1642static const unsigned char aes_test_ofb_iv[16] =
1643{
1644 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1645 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1646};
1647
1648static const unsigned char aes_test_ofb_pt[64] =
1649{
1650 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1651 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1652 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1653 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1654 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1655 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1656 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1657 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1658};
1659
Yanray Wang62c99912023-05-11 11:06:53 +08001660static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001661{
1662 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1663 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1664 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1665 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1666 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1667 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1668 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1669 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001670#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001671 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1672 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1673 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1674 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1675 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1676 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1677 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1678 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1679 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1680 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1681 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1682 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1683 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1684 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1685 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1686 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001687#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001688};
1689#endif /* MBEDTLS_CIPHER_MODE_OFB */
1690
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001691#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001692/*
1693 * AES-CTR test vectors from:
1694 *
1695 * http://www.faqs.org/rfcs/rfc3686.html
1696 */
1697
Yanray Wang62c99912023-05-11 11:06:53 +08001698static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001699{
1700 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1701 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1702 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1703 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1704 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1705 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1706};
1707
Yanray Wang62c99912023-05-11 11:06:53 +08001708static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001709{
1710 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1712 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1713 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1714 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1715 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1716};
1717
Yanray Wang62c99912023-05-11 11:06:53 +08001718static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001719{
1720 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1721 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001722 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1723 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1724 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1725 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1726
1727 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1728 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1729 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1730 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1731 0x20, 0x21, 0x22, 0x23 }
1732};
1733
Yanray Wang62c99912023-05-11 11:06:53 +08001734static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001735{
1736 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1737 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1738 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1739 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1740 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1741 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1742 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1743 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1744 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1745 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1746 0x25, 0xB2, 0x07, 0x2F }
1747};
1748
1749static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001750{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001751#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001752
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001753#if defined(MBEDTLS_CIPHER_MODE_XTS)
1754/*
1755 * AES-XTS test vectors from:
1756 *
1757 * IEEE P1619/D16 Annex B
1758 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1759 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1760 */
1761static const unsigned char aes_test_xts_key[][32] =
1762{
1763 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1767 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1768 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1769 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1770 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1771 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1772 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1773 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1774 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1775};
1776
1777static const unsigned char aes_test_xts_pt32[][32] =
1778{
1779 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1783 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1784 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1785 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1786 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1787 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1788 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1789 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1790 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1791};
1792
1793static const unsigned char aes_test_xts_ct32[][32] =
1794{
1795 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1796 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1797 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1798 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1799 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1800 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1801 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1802 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1803 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1804 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1805 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1806 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1807};
1808
1809static const unsigned char aes_test_xts_data_unit[][16] =
1810{
Gilles Peskine449bd832023-01-11 14:50:10 +01001811 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1813 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1815 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001817};
1818
1819#endif /* MBEDTLS_CIPHER_MODE_XTS */
1820
Paul Bakker5121ce52009-01-03 21:22:43 +00001821/*
1822 * Checkup routine
1823 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001824int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001825{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001826 int ret = 0, i, j, u, mode;
1827 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001828 unsigned char key[32];
1829 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001830 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001831#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1832 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001833 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001834#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001835#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001836 unsigned char prv[16];
1837#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001838#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1839 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001840 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001841#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001842#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001843 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001844#endif
1845#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001846 unsigned char nonce_counter[16];
1847 unsigned char stream_block[16];
1848#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001849 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001850
Gilles Peskine449bd832023-01-11 14:50:10 +01001851 memset(key, 0, 32);
1852 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001853
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001854 if (verbose != 0) {
1855#if defined(MBEDTLS_AES_ALT)
1856 mbedtls_printf(" AES note: alternative implementation.\n");
1857#else /* MBEDTLS_AES_ALT */
1858#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1859 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1860 mbedtls_printf(" AES note: using VIA Padlock.\n");
1861 } else
1862#endif
1863#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001864#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001865 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001866#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001867 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001868#else
Antonio de Angelis1ee4d122023-08-16 12:26:37 +01001869#error "Unrecognised value for MBEDTLS_AESNI_HAVE_CODE"
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001870#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001871 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1872 mbedtls_printf(" AES note: using AESNI.\n");
1873 } else
1874#endif
1875#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1876 if (mbedtls_aesce_has_support()) {
1877 mbedtls_printf(" AES note: using AESCE.\n");
1878 } else
1879#endif
1880 mbedtls_printf(" AES note: built-in implementation.\n");
1881#endif /* MBEDTLS_AES_ALT */
1882 }
1883
Paul Bakker5121ce52009-01-03 21:22:43 +00001884 /*
1885 * ECB mode
1886 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001887 {
1888 static const int num_tests =
1889 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001890
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001891 for (i = 0; i < num_tests << 1; i++) {
1892 u = i >> 1;
1893 keybits = 128 + u * 64;
1894 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001895
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001896 if (verbose != 0) {
1897 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1898 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1899 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001900
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001901 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001902
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001903 if (mode == MBEDTLS_AES_DECRYPT) {
1904 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1905 aes_tests = aes_test_ecb_dec[u];
1906 } else {
1907 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1908 aes_tests = aes_test_ecb_enc[u];
1909 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001910
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001911 /*
1912 * AES-192 is an optional feature that may be unavailable when
1913 * there is an alternative underlying implementation i.e. when
1914 * MBEDTLS_AES_ALT is defined.
1915 */
1916 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1917 mbedtls_printf("skipped\n");
1918 continue;
1919 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001920 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001921 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001922
1923 for (j = 0; j < 10000; j++) {
1924 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1925 if (ret != 0) {
1926 goto exit;
1927 }
1928 }
1929
1930 if (memcmp(buf, aes_tests, 16) != 0) {
1931 ret = 1;
1932 goto exit;
1933 }
1934
1935 if (verbose != 0) {
1936 mbedtls_printf("passed\n");
1937 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001938 }
1939
Gilles Peskine449bd832023-01-11 14:50:10 +01001940 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001941 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001942 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001943 }
1944
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001945#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001946 /*
1947 * CBC mode
1948 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001949 {
1950 static const int num_tests =
1951 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001952
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001953 for (i = 0; i < num_tests << 1; i++) {
1954 u = i >> 1;
1955 keybits = 128 + u * 64;
1956 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001957
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001958 if (verbose != 0) {
1959 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1960 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001961 }
1962
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001963 memset(iv, 0, 16);
1964 memset(prv, 0, 16);
1965 memset(buf, 0, 16);
1966
1967 if (mode == MBEDTLS_AES_DECRYPT) {
1968 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1969 aes_tests = aes_test_cbc_dec[u];
1970 } else {
1971 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1972 aes_tests = aes_test_cbc_enc[u];
1973 }
1974
1975 /*
1976 * AES-192 is an optional feature that may be unavailable when
1977 * there is an alternative underlying implementation i.e. when
1978 * MBEDTLS_AES_ALT is defined.
1979 */
1980 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1981 mbedtls_printf("skipped\n");
1982 continue;
1983 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001984 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001985 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001986
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001987 for (j = 0; j < 10000; j++) {
1988 if (mode == MBEDTLS_AES_ENCRYPT) {
1989 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001990
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001991 memcpy(tmp, prv, 16);
1992 memcpy(prv, buf, 16);
1993 memcpy(buf, tmp, 16);
1994 }
1995
1996 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
1997 if (ret != 0) {
1998 goto exit;
1999 }
2000
2001 }
2002
2003 if (memcmp(buf, aes_tests, 16) != 0) {
2004 ret = 1;
2005 goto exit;
2006 }
2007
2008 if (verbose != 0) {
2009 mbedtls_printf("passed\n");
2010 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002011 }
2012
Gilles Peskine449bd832023-01-11 14:50:10 +01002013 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002014 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002015 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002016 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002017#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002018
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002019#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002020 /*
2021 * CFB128 mode
2022 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002023 {
2024 static const int num_tests =
2025 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002026
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002027 for (i = 0; i < num_tests << 1; i++) {
2028 u = i >> 1;
2029 keybits = 128 + u * 64;
2030 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002031
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002032 if (verbose != 0) {
2033 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2034 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2035 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002036
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002037 memcpy(iv, aes_test_cfb128_iv, 16);
2038 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002039
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002040 offset = 0;
2041 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2042 /*
2043 * AES-192 is an optional feature that may be unavailable when
2044 * there is an alternative underlying implementation i.e. when
2045 * MBEDTLS_AES_ALT is defined.
2046 */
2047 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2048 mbedtls_printf("skipped\n");
2049 continue;
2050 } else if (ret != 0) {
2051 goto exit;
2052 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002053
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002054 if (mode == MBEDTLS_AES_DECRYPT) {
2055 memcpy(buf, aes_test_cfb128_ct[u], 64);
2056 aes_tests = aes_test_cfb128_pt;
2057 } else {
2058 memcpy(buf, aes_test_cfb128_pt, 64);
2059 aes_tests = aes_test_cfb128_ct[u];
2060 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002061
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002062 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2063 if (ret != 0) {
2064 goto exit;
2065 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002066
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002067 if (memcmp(buf, aes_tests, 64) != 0) {
2068 ret = 1;
2069 goto exit;
2070 }
2071
2072 if (verbose != 0) {
2073 mbedtls_printf("passed\n");
2074 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 }
2076
Gilles Peskine449bd832023-01-11 14:50:10 +01002077 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002078 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002079 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002080 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002081#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002082
Simon Butcherad4e4932018-04-29 00:43:47 +01002083#if defined(MBEDTLS_CIPHER_MODE_OFB)
2084 /*
2085 * OFB mode
2086 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002087 {
2088 static const int num_tests =
2089 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002090
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002091 for (i = 0; i < num_tests << 1; i++) {
2092 u = i >> 1;
2093 keybits = 128 + u * 64;
2094 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002095
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 if (verbose != 0) {
2097 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2098 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2099 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002100
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002101 memcpy(iv, aes_test_ofb_iv, 16);
2102 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002103
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002104 offset = 0;
2105 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2106 /*
2107 * AES-192 is an optional feature that may be unavailable when
2108 * there is an alternative underlying implementation i.e. when
2109 * MBEDTLS_AES_ALT is defined.
2110 */
2111 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2112 mbedtls_printf("skipped\n");
2113 continue;
2114 } else if (ret != 0) {
2115 goto exit;
2116 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002117
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002118 if (mode == MBEDTLS_AES_DECRYPT) {
2119 memcpy(buf, aes_test_ofb_ct[u], 64);
2120 aes_tests = aes_test_ofb_pt;
2121 } else {
2122 memcpy(buf, aes_test_ofb_pt, 64);
2123 aes_tests = aes_test_ofb_ct[u];
2124 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002125
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002126 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2127 if (ret != 0) {
2128 goto exit;
2129 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002130
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002131 if (memcmp(buf, aes_tests, 64) != 0) {
2132 ret = 1;
2133 goto exit;
2134 }
2135
2136 if (verbose != 0) {
2137 mbedtls_printf("passed\n");
2138 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002139 }
2140
Gilles Peskine449bd832023-01-11 14:50:10 +01002141 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002142 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002143 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002144 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002145#endif /* MBEDTLS_CIPHER_MODE_OFB */
2146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002147#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002148 /*
2149 * CTR mode
2150 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002151 {
2152 static const int num_tests =
2153 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002154
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002155 for (i = 0; i < num_tests << 1; i++) {
2156 u = i >> 1;
2157 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002158
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002159 if (verbose != 0) {
2160 mbedtls_printf(" AES-CTR-128 (%s): ",
2161 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2162 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002163
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002164 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2165 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002166
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002167 offset = 0;
2168 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2169 goto exit;
2170 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002171
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002172 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002173
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002174 if (mode == MBEDTLS_AES_DECRYPT) {
2175 memcpy(buf, aes_test_ctr_ct[u], len);
2176 aes_tests = aes_test_ctr_pt[u];
2177 } else {
2178 memcpy(buf, aes_test_ctr_pt[u], len);
2179 aes_tests = aes_test_ctr_ct[u];
2180 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002181
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002182 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2183 stream_block, buf, buf);
2184 if (ret != 0) {
2185 goto exit;
2186 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002187
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002188 if (memcmp(buf, aes_tests, len) != 0) {
2189 ret = 1;
2190 goto exit;
2191 }
2192
2193 if (verbose != 0) {
2194 mbedtls_printf("passed\n");
2195 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002196 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002197 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002198
Gilles Peskine449bd832023-01-11 14:50:10 +01002199 if (verbose != 0) {
2200 mbedtls_printf("\n");
2201 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002202#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002203
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002204#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002205 /*
2206 * XTS mode
2207 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002208 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002209 static const int num_tests =
2210 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2211 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002212
Gilles Peskine449bd832023-01-11 14:50:10 +01002213 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002214
Gilles Peskine449bd832023-01-11 14:50:10 +01002215 for (i = 0; i < num_tests << 1; i++) {
2216 const unsigned char *data_unit;
2217 u = i >> 1;
2218 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002219
Gilles Peskine449bd832023-01-11 14:50:10 +01002220 if (verbose != 0) {
2221 mbedtls_printf(" AES-XTS-128 (%s): ",
2222 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2223 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002224
Gilles Peskine449bd832023-01-11 14:50:10 +01002225 memset(key, 0, sizeof(key));
2226 memcpy(key, aes_test_xts_key[u], 32);
2227 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002228
Gilles Peskine449bd832023-01-11 14:50:10 +01002229 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002230
Gilles Peskine449bd832023-01-11 14:50:10 +01002231 if (mode == MBEDTLS_AES_DECRYPT) {
2232 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2233 if (ret != 0) {
2234 goto exit;
2235 }
2236 memcpy(buf, aes_test_xts_ct32[u], len);
2237 aes_tests = aes_test_xts_pt32[u];
2238 } else {
2239 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2240 if (ret != 0) {
2241 goto exit;
2242 }
2243 memcpy(buf, aes_test_xts_pt32[u], len);
2244 aes_tests = aes_test_xts_ct32[u];
2245 }
2246
2247
2248 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2249 buf, buf);
2250 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002251 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002252 }
2253
2254 if (memcmp(buf, aes_tests, len) != 0) {
2255 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002256 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002257 }
2258
2259 if (verbose != 0) {
2260 mbedtls_printf("passed\n");
2261 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002262 }
2263
Gilles Peskine449bd832023-01-11 14:50:10 +01002264 if (verbose != 0) {
2265 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002266 }
2267
Gilles Peskine449bd832023-01-11 14:50:10 +01002268 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002269 }
2270#endif /* MBEDTLS_CIPHER_MODE_XTS */
2271
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002272 ret = 0;
2273
2274exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002275 if (ret != 0 && verbose != 0) {
2276 mbedtls_printf("failed\n");
2277 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002278
Gilles Peskine449bd832023-01-11 14:50:10 +01002279 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002280
Gilles Peskine449bd832023-01-11 14:50:10 +01002281 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002282}
2283
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002284#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002286#endif /* MBEDTLS_AES_C */