blob: 4cb9ce1c1459b2211c6a74650ce15905cff77d04 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * FIPS-197 compliant AES implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
21 *
22 * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
23 * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_AES_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Rich Evans00ab4702015-02-06 13:43:58 +000030#include <string.h>
31
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/aes.h"
Ron Eldor9924bdc2018-10-04 10:59:13 +030033#include "mbedtls/platform.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050034#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000035#include "mbedtls/error.h"
Jerry Yu02b15192023-04-23 14:43:19 +080036
Jerry Yuba42b072023-08-10 12:53:26 +080037#if defined(__aarch64__)
Jerry Yu02b15192023-04-23 14:43:19 +080038#if !defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080039#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080040#endif
41#endif
42
Jerry Yu8189f322023-08-10 13:53:41 +080043#if defined(__amd64__) || defined(__x86_64__)
Jerry Yu02b15192023-04-23 14:43:19 +080044#if !defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Jerry Yu69436812023-04-25 11:08:30 +080045#error "MBEDTLS_AES_USE_HARDWARE_ONLY defined, but not all prerequisites"
Jerry Yu02b15192023-04-23 14:43:19 +080046#endif
47#endif
48
Jerry Yu13696bb2023-08-10 13:36:32 +080049#if defined(__i386__)
Jerry Yuc4508c02023-08-08 12:57:06 +080050#if defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
51#error "MBEDTLS_AES_USE_HARDWARE_ONLY not supported yet for i386."
Jerry Yu02b15192023-04-23 14:43:19 +080052#endif
Jerry Yu13696bb2023-08-10 13:36:32 +080053
54#if defined(MBEDTLS_PADLOCK_C) && !defined(MBEDTLS_HAVE_ASM)
55#error "MBEDTLS_PADLOCK_C defined, but not all prerequisites"
56#endif
Jerry Yu02b15192023-04-23 14:43:19 +080057#endif
58
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_PADLOCK_C)
Chris Jones16dbaeb2021-03-09 17:47:55 +000060#include "padlock.h"
Paul Bakker67820bd2012-06-04 12:47:23 +000061#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062#if defined(MBEDTLS_AESNI_C)
Chris Jones187782f2021-03-09 17:28:35 +000063#include "aesni.h"
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +010064#endif
Jerry Yu3f2fb712023-01-10 17:05:42 +080065#if defined(MBEDTLS_AESCE_C)
66#include "aesce.h"
67#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000068
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000069#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010070
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071#if !defined(MBEDTLS_AES_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020072
Gilles Peskine0f454e42023-03-16 14:58:46 +010073#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Paul Bakker048d04e2012-02-12 17:31:04 +000074static int aes_padlock_ace = -1;
75#endif
76
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077#if defined(MBEDTLS_AES_ROM_TABLES)
Paul Bakker5121ce52009-01-03 21:22:43 +000078/*
79 * Forward S-box
80 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +010081#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
82 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +000083static const unsigned char FSb[256] =
84{
85 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
86 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
87 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
88 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
89 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
90 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
91 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
92 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
93 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
94 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
95 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
96 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
97 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
98 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
99 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
100 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
101 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
102 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
103 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
104 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
105 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
106 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
107 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
108 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
109 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
110 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
111 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
112 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
113 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
114 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
115 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
116 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
117};
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100118#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
119 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000120
121/*
122 * Forward tables
123 */
124#define FT \
125\
Gilles Peskine449bd832023-01-11 14:50:10 +0100126 V(A5, 63, 63, C6), V(84, 7C, 7C, F8), V(99, 77, 77, EE), V(8D, 7B, 7B, F6), \
127 V(0D, F2, F2, FF), V(BD, 6B, 6B, D6), V(B1, 6F, 6F, DE), V(54, C5, C5, 91), \
128 V(50, 30, 30, 60), V(03, 01, 01, 02), V(A9, 67, 67, CE), V(7D, 2B, 2B, 56), \
129 V(19, FE, FE, E7), V(62, D7, D7, B5), V(E6, AB, AB, 4D), V(9A, 76, 76, EC), \
130 V(45, CA, CA, 8F), V(9D, 82, 82, 1F), V(40, C9, C9, 89), V(87, 7D, 7D, FA), \
131 V(15, FA, FA, EF), V(EB, 59, 59, B2), V(C9, 47, 47, 8E), V(0B, F0, F0, FB), \
132 V(EC, AD, AD, 41), V(67, D4, D4, B3), V(FD, A2, A2, 5F), V(EA, AF, AF, 45), \
133 V(BF, 9C, 9C, 23), V(F7, A4, A4, 53), V(96, 72, 72, E4), V(5B, C0, C0, 9B), \
134 V(C2, B7, B7, 75), V(1C, FD, FD, E1), V(AE, 93, 93, 3D), V(6A, 26, 26, 4C), \
135 V(5A, 36, 36, 6C), V(41, 3F, 3F, 7E), V(02, F7, F7, F5), V(4F, CC, CC, 83), \
136 V(5C, 34, 34, 68), V(F4, A5, A5, 51), V(34, E5, E5, D1), V(08, F1, F1, F9), \
137 V(93, 71, 71, E2), V(73, D8, D8, AB), V(53, 31, 31, 62), V(3F, 15, 15, 2A), \
138 V(0C, 04, 04, 08), V(52, C7, C7, 95), V(65, 23, 23, 46), V(5E, C3, C3, 9D), \
139 V(28, 18, 18, 30), V(A1, 96, 96, 37), V(0F, 05, 05, 0A), V(B5, 9A, 9A, 2F), \
140 V(09, 07, 07, 0E), V(36, 12, 12, 24), V(9B, 80, 80, 1B), V(3D, E2, E2, DF), \
141 V(26, EB, EB, CD), V(69, 27, 27, 4E), V(CD, B2, B2, 7F), V(9F, 75, 75, EA), \
142 V(1B, 09, 09, 12), V(9E, 83, 83, 1D), V(74, 2C, 2C, 58), V(2E, 1A, 1A, 34), \
143 V(2D, 1B, 1B, 36), V(B2, 6E, 6E, DC), V(EE, 5A, 5A, B4), V(FB, A0, A0, 5B), \
144 V(F6, 52, 52, A4), V(4D, 3B, 3B, 76), V(61, D6, D6, B7), V(CE, B3, B3, 7D), \
145 V(7B, 29, 29, 52), V(3E, E3, E3, DD), V(71, 2F, 2F, 5E), V(97, 84, 84, 13), \
146 V(F5, 53, 53, A6), V(68, D1, D1, B9), V(00, 00, 00, 00), V(2C, ED, ED, C1), \
147 V(60, 20, 20, 40), V(1F, FC, FC, E3), V(C8, B1, B1, 79), V(ED, 5B, 5B, B6), \
148 V(BE, 6A, 6A, D4), V(46, CB, CB, 8D), V(D9, BE, BE, 67), V(4B, 39, 39, 72), \
149 V(DE, 4A, 4A, 94), V(D4, 4C, 4C, 98), V(E8, 58, 58, B0), V(4A, CF, CF, 85), \
150 V(6B, D0, D0, BB), V(2A, EF, EF, C5), V(E5, AA, AA, 4F), V(16, FB, FB, ED), \
151 V(C5, 43, 43, 86), V(D7, 4D, 4D, 9A), V(55, 33, 33, 66), V(94, 85, 85, 11), \
152 V(CF, 45, 45, 8A), V(10, F9, F9, E9), V(06, 02, 02, 04), V(81, 7F, 7F, FE), \
153 V(F0, 50, 50, A0), V(44, 3C, 3C, 78), V(BA, 9F, 9F, 25), V(E3, A8, A8, 4B), \
154 V(F3, 51, 51, A2), V(FE, A3, A3, 5D), V(C0, 40, 40, 80), V(8A, 8F, 8F, 05), \
155 V(AD, 92, 92, 3F), V(BC, 9D, 9D, 21), V(48, 38, 38, 70), V(04, F5, F5, F1), \
156 V(DF, BC, BC, 63), V(C1, B6, B6, 77), V(75, DA, DA, AF), V(63, 21, 21, 42), \
157 V(30, 10, 10, 20), V(1A, FF, FF, E5), V(0E, F3, F3, FD), V(6D, D2, D2, BF), \
158 V(4C, CD, CD, 81), V(14, 0C, 0C, 18), V(35, 13, 13, 26), V(2F, EC, EC, C3), \
159 V(E1, 5F, 5F, BE), V(A2, 97, 97, 35), V(CC, 44, 44, 88), V(39, 17, 17, 2E), \
160 V(57, C4, C4, 93), V(F2, A7, A7, 55), V(82, 7E, 7E, FC), V(47, 3D, 3D, 7A), \
161 V(AC, 64, 64, C8), V(E7, 5D, 5D, BA), V(2B, 19, 19, 32), V(95, 73, 73, E6), \
162 V(A0, 60, 60, C0), V(98, 81, 81, 19), V(D1, 4F, 4F, 9E), V(7F, DC, DC, A3), \
163 V(66, 22, 22, 44), V(7E, 2A, 2A, 54), V(AB, 90, 90, 3B), V(83, 88, 88, 0B), \
164 V(CA, 46, 46, 8C), V(29, EE, EE, C7), V(D3, B8, B8, 6B), V(3C, 14, 14, 28), \
165 V(79, DE, DE, A7), V(E2, 5E, 5E, BC), V(1D, 0B, 0B, 16), V(76, DB, DB, AD), \
166 V(3B, E0, E0, DB), V(56, 32, 32, 64), V(4E, 3A, 3A, 74), V(1E, 0A, 0A, 14), \
167 V(DB, 49, 49, 92), V(0A, 06, 06, 0C), V(6C, 24, 24, 48), V(E4, 5C, 5C, B8), \
168 V(5D, C2, C2, 9F), V(6E, D3, D3, BD), V(EF, AC, AC, 43), V(A6, 62, 62, C4), \
169 V(A8, 91, 91, 39), V(A4, 95, 95, 31), V(37, E4, E4, D3), V(8B, 79, 79, F2), \
170 V(32, E7, E7, D5), V(43, C8, C8, 8B), V(59, 37, 37, 6E), V(B7, 6D, 6D, DA), \
171 V(8C, 8D, 8D, 01), V(64, D5, D5, B1), V(D2, 4E, 4E, 9C), V(E0, A9, A9, 49), \
172 V(B4, 6C, 6C, D8), V(FA, 56, 56, AC), V(07, F4, F4, F3), V(25, EA, EA, CF), \
173 V(AF, 65, 65, CA), V(8E, 7A, 7A, F4), V(E9, AE, AE, 47), V(18, 08, 08, 10), \
174 V(D5, BA, BA, 6F), V(88, 78, 78, F0), V(6F, 25, 25, 4A), V(72, 2E, 2E, 5C), \
175 V(24, 1C, 1C, 38), V(F1, A6, A6, 57), V(C7, B4, B4, 73), V(51, C6, C6, 97), \
176 V(23, E8, E8, CB), V(7C, DD, DD, A1), V(9C, 74, 74, E8), V(21, 1F, 1F, 3E), \
177 V(DD, 4B, 4B, 96), V(DC, BD, BD, 61), V(86, 8B, 8B, 0D), V(85, 8A, 8A, 0F), \
178 V(90, 70, 70, E0), V(42, 3E, 3E, 7C), V(C4, B5, B5, 71), V(AA, 66, 66, CC), \
179 V(D8, 48, 48, 90), V(05, 03, 03, 06), V(01, F6, F6, F7), V(12, 0E, 0E, 1C), \
180 V(A3, 61, 61, C2), V(5F, 35, 35, 6A), V(F9, 57, 57, AE), V(D0, B9, B9, 69), \
181 V(91, 86, 86, 17), V(58, C1, C1, 99), V(27, 1D, 1D, 3A), V(B9, 9E, 9E, 27), \
182 V(38, E1, E1, D9), V(13, F8, F8, EB), V(B3, 98, 98, 2B), V(33, 11, 11, 22), \
183 V(BB, 69, 69, D2), V(70, D9, D9, A9), V(89, 8E, 8E, 07), V(A7, 94, 94, 33), \
184 V(B6, 9B, 9B, 2D), V(22, 1E, 1E, 3C), V(92, 87, 87, 15), V(20, E9, E9, C9), \
185 V(49, CE, CE, 87), V(FF, 55, 55, AA), V(78, 28, 28, 50), V(7A, DF, DF, A5), \
186 V(8F, 8C, 8C, 03), V(F8, A1, A1, 59), V(80, 89, 89, 09), V(17, 0D, 0D, 1A), \
187 V(DA, BF, BF, 65), V(31, E6, E6, D7), V(C6, 42, 42, 84), V(B8, 68, 68, D0), \
188 V(C3, 41, 41, 82), V(B0, 99, 99, 29), V(77, 2D, 2D, 5A), V(11, 0F, 0F, 1E), \
189 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 +0000190
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100191#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100192#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000193static const uint32_t FT0[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000194#undef V
195
Hanno Beckerad049a92017-06-19 16:31:54 +0100196#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000199static const uint32_t FT1[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000200#undef V
201
Gilles Peskine449bd832023-01-11 14:50:10 +0100202#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000203static const uint32_t FT2[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000204#undef V
205
Gilles Peskine449bd832023-01-11 14:50:10 +0100206#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000207static const uint32_t FT3[256] = { FT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000208#undef V
209
Hanno Becker177d3cf2017-06-07 15:52:48 +0100210#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200211
Dave Rodgman1be24632023-06-29 12:01:24 +0100212#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) */
213
Paul Bakker5121ce52009-01-03 21:22:43 +0000214#undef FT
215
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100216#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000217/*
218 * Reverse S-box
219 */
220static const unsigned char RSb[256] =
221{
222 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
223 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
224 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
225 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
226 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
227 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
228 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
229 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
230 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
231 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
232 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
233 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
234 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
235 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
236 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
237 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
238 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
239 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
240 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
241 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
242 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
243 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
244 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
245 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
246 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
247 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
248 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
249 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
250 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
251 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
252 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
253 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
254};
Dave Rodgman710e3c62023-06-29 11:58:04 +0100255#endif /* defined(MBEDTLS_AES_DECRYPT_ALT)) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
257/*
258 * Reverse tables
259 */
260#define RT \
261\
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 V(50, A7, F4, 51), V(53, 65, 41, 7E), V(C3, A4, 17, 1A), V(96, 5E, 27, 3A), \
263 V(CB, 6B, AB, 3B), V(F1, 45, 9D, 1F), V(AB, 58, FA, AC), V(93, 03, E3, 4B), \
264 V(55, FA, 30, 20), V(F6, 6D, 76, AD), V(91, 76, CC, 88), V(25, 4C, 02, F5), \
265 V(FC, D7, E5, 4F), V(D7, CB, 2A, C5), V(80, 44, 35, 26), V(8F, A3, 62, B5), \
266 V(49, 5A, B1, DE), V(67, 1B, BA, 25), V(98, 0E, EA, 45), V(E1, C0, FE, 5D), \
267 V(02, 75, 2F, C3), V(12, F0, 4C, 81), V(A3, 97, 46, 8D), V(C6, F9, D3, 6B), \
268 V(E7, 5F, 8F, 03), V(95, 9C, 92, 15), V(EB, 7A, 6D, BF), V(DA, 59, 52, 95), \
269 V(2D, 83, BE, D4), V(D3, 21, 74, 58), V(29, 69, E0, 49), V(44, C8, C9, 8E), \
270 V(6A, 89, C2, 75), V(78, 79, 8E, F4), V(6B, 3E, 58, 99), V(DD, 71, B9, 27), \
271 V(B6, 4F, E1, BE), V(17, AD, 88, F0), V(66, AC, 20, C9), V(B4, 3A, CE, 7D), \
272 V(18, 4A, DF, 63), V(82, 31, 1A, E5), V(60, 33, 51, 97), V(45, 7F, 53, 62), \
273 V(E0, 77, 64, B1), V(84, AE, 6B, BB), V(1C, A0, 81, FE), V(94, 2B, 08, F9), \
274 V(58, 68, 48, 70), V(19, FD, 45, 8F), V(87, 6C, DE, 94), V(B7, F8, 7B, 52), \
275 V(23, D3, 73, AB), V(E2, 02, 4B, 72), V(57, 8F, 1F, E3), V(2A, AB, 55, 66), \
276 V(07, 28, EB, B2), V(03, C2, B5, 2F), V(9A, 7B, C5, 86), V(A5, 08, 37, D3), \
277 V(F2, 87, 28, 30), V(B2, A5, BF, 23), V(BA, 6A, 03, 02), V(5C, 82, 16, ED), \
278 V(2B, 1C, CF, 8A), V(92, B4, 79, A7), V(F0, F2, 07, F3), V(A1, E2, 69, 4E), \
279 V(CD, F4, DA, 65), V(D5, BE, 05, 06), V(1F, 62, 34, D1), V(8A, FE, A6, C4), \
280 V(9D, 53, 2E, 34), V(A0, 55, F3, A2), V(32, E1, 8A, 05), V(75, EB, F6, A4), \
281 V(39, EC, 83, 0B), V(AA, EF, 60, 40), V(06, 9F, 71, 5E), V(51, 10, 6E, BD), \
282 V(F9, 8A, 21, 3E), V(3D, 06, DD, 96), V(AE, 05, 3E, DD), V(46, BD, E6, 4D), \
283 V(B5, 8D, 54, 91), V(05, 5D, C4, 71), V(6F, D4, 06, 04), V(FF, 15, 50, 60), \
284 V(24, FB, 98, 19), V(97, E9, BD, D6), V(CC, 43, 40, 89), V(77, 9E, D9, 67), \
285 V(BD, 42, E8, B0), V(88, 8B, 89, 07), V(38, 5B, 19, E7), V(DB, EE, C8, 79), \
286 V(47, 0A, 7C, A1), V(E9, 0F, 42, 7C), V(C9, 1E, 84, F8), V(00, 00, 00, 00), \
287 V(83, 86, 80, 09), V(48, ED, 2B, 32), V(AC, 70, 11, 1E), V(4E, 72, 5A, 6C), \
288 V(FB, FF, 0E, FD), V(56, 38, 85, 0F), V(1E, D5, AE, 3D), V(27, 39, 2D, 36), \
289 V(64, D9, 0F, 0A), V(21, A6, 5C, 68), V(D1, 54, 5B, 9B), V(3A, 2E, 36, 24), \
290 V(B1, 67, 0A, 0C), V(0F, E7, 57, 93), V(D2, 96, EE, B4), V(9E, 91, 9B, 1B), \
291 V(4F, C5, C0, 80), V(A2, 20, DC, 61), V(69, 4B, 77, 5A), V(16, 1A, 12, 1C), \
292 V(0A, BA, 93, E2), V(E5, 2A, A0, C0), V(43, E0, 22, 3C), V(1D, 17, 1B, 12), \
293 V(0B, 0D, 09, 0E), V(AD, C7, 8B, F2), V(B9, A8, B6, 2D), V(C8, A9, 1E, 14), \
294 V(85, 19, F1, 57), V(4C, 07, 75, AF), V(BB, DD, 99, EE), V(FD, 60, 7F, A3), \
295 V(9F, 26, 01, F7), V(BC, F5, 72, 5C), V(C5, 3B, 66, 44), V(34, 7E, FB, 5B), \
296 V(76, 29, 43, 8B), V(DC, C6, 23, CB), V(68, FC, ED, B6), V(63, F1, E4, B8), \
297 V(CA, DC, 31, D7), V(10, 85, 63, 42), V(40, 22, 97, 13), V(20, 11, C6, 84), \
298 V(7D, 24, 4A, 85), V(F8, 3D, BB, D2), V(11, 32, F9, AE), V(6D, A1, 29, C7), \
299 V(4B, 2F, 9E, 1D), V(F3, 30, B2, DC), V(EC, 52, 86, 0D), V(D0, E3, C1, 77), \
300 V(6C, 16, B3, 2B), V(99, B9, 70, A9), V(FA, 48, 94, 11), V(22, 64, E9, 47), \
301 V(C4, 8C, FC, A8), V(1A, 3F, F0, A0), V(D8, 2C, 7D, 56), V(EF, 90, 33, 22), \
302 V(C7, 4E, 49, 87), V(C1, D1, 38, D9), V(FE, A2, CA, 8C), V(36, 0B, D4, 98), \
303 V(CF, 81, F5, A6), V(28, DE, 7A, A5), V(26, 8E, B7, DA), V(A4, BF, AD, 3F), \
304 V(E4, 9D, 3A, 2C), V(0D, 92, 78, 50), V(9B, CC, 5F, 6A), V(62, 46, 7E, 54), \
305 V(C2, 13, 8D, F6), V(E8, B8, D8, 90), V(5E, F7, 39, 2E), V(F5, AF, C3, 82), \
306 V(BE, 80, 5D, 9F), V(7C, 93, D0, 69), V(A9, 2D, D5, 6F), V(B3, 12, 25, CF), \
307 V(3B, 99, AC, C8), V(A7, 7D, 18, 10), V(6E, 63, 9C, E8), V(7B, BB, 3B, DB), \
308 V(09, 78, 26, CD), V(F4, 18, 59, 6E), V(01, B7, 9A, EC), V(A8, 9A, 4F, 83), \
309 V(65, 6E, 95, E6), V(7E, E6, FF, AA), V(08, CF, BC, 21), V(E6, E8, 15, EF), \
310 V(D9, 9B, E7, BA), V(CE, 36, 6F, 4A), V(D4, 09, 9F, EA), V(D6, 7C, B0, 29), \
311 V(AF, B2, A4, 31), V(31, 23, 3F, 2A), V(30, 94, A5, C6), V(C0, 66, A2, 35), \
312 V(37, BC, 4E, 74), V(A6, CA, 82, FC), V(B0, D0, 90, E0), V(15, D8, A7, 33), \
313 V(4A, 98, 04, F1), V(F7, DA, EC, 41), V(0E, 50, CD, 7F), V(2F, F6, 91, 17), \
314 V(8D, D6, 4D, 76), V(4D, B0, EF, 43), V(54, 4D, AA, CC), V(DF, 04, 96, E4), \
315 V(E3, B5, D1, 9E), V(1B, 88, 6A, 4C), V(B8, 1F, 2C, C1), V(7F, 51, 65, 46), \
316 V(04, EA, 5E, 9D), V(5D, 35, 8C, 01), V(73, 74, 87, FA), V(2E, 41, 0B, FB), \
317 V(5A, 1D, 67, B3), V(52, D2, DB, 92), V(33, 56, 10, E9), V(13, 47, D6, 6D), \
318 V(8C, 61, D7, 9A), V(7A, 0C, A1, 37), V(8E, 14, F8, 59), V(89, 3C, 13, EB), \
319 V(EE, 27, A9, CE), V(35, C9, 61, B7), V(ED, E5, 1C, E1), V(3C, B1, 47, 7A), \
320 V(59, DF, D2, 9C), V(3F, 73, F2, 55), V(79, CE, 14, 18), V(BF, 37, C7, 73), \
321 V(EA, CD, F7, 53), V(5B, AA, FD, 5F), V(14, 6F, 3D, DF), V(86, DB, 44, 78), \
322 V(81, F3, AF, CA), V(3E, C4, 68, B9), V(2C, 34, 24, 38), V(5F, 40, A3, C2), \
323 V(72, C3, 1D, 16), V(0C, 25, E2, BC), V(8B, 49, 3C, 28), V(41, 95, 0D, FF), \
324 V(71, 01, A8, 39), V(DE, B3, 0C, 08), V(9C, E4, B4, D8), V(90, C1, 56, 64), \
325 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 +0000326
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100327#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
328
Gilles Peskine449bd832023-01-11 14:50:10 +0100329#define V(a, b, c, d) 0x##a##b##c##d
Paul Bakker5c2364c2012-10-01 14:41:15 +0000330static const uint32_t RT0[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000331#undef V
332
Hanno Beckerad049a92017-06-19 16:31:54 +0100333#if !defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200334
Gilles Peskine449bd832023-01-11 14:50:10 +0100335#define V(a, b, c, d) 0x##b##c##d##a
Paul Bakker5c2364c2012-10-01 14:41:15 +0000336static const uint32_t RT1[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000337#undef V
338
Gilles Peskine449bd832023-01-11 14:50:10 +0100339#define V(a, b, c, d) 0x##c##d##a##b
Paul Bakker5c2364c2012-10-01 14:41:15 +0000340static const uint32_t RT2[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000341#undef V
342
Gilles Peskine449bd832023-01-11 14:50:10 +0100343#define V(a, b, c, d) 0x##d##a##b##c
Paul Bakker5c2364c2012-10-01 14:41:15 +0000344static const uint32_t RT3[256] = { RT };
Paul Bakker5121ce52009-01-03 21:22:43 +0000345#undef V
346
Hanno Becker177d3cf2017-06-07 15:52:48 +0100347#endif /* !MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200348
Yanray Wang5adfdbd2023-07-06 17:10:41 +0800349#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
350
Paul Bakker5121ce52009-01-03 21:22:43 +0000351#undef RT
352
Dave Rodgman34152a42023-06-27 18:31:24 +0100353#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000354/*
355 * Round constants
356 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000357static const uint32_t RCON[10] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000358{
359 0x00000001, 0x00000002, 0x00000004, 0x00000008,
360 0x00000010, 0x00000020, 0x00000040, 0x00000080,
361 0x0000001B, 0x00000036
362};
Dave Rodgman34152a42023-06-27 18:31:24 +0100363#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365#else /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000366
367/*
368 * Forward S-box & tables
369 */
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100370#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
371 !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000372static unsigned char FSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100373#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) || \
374 !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100375#if !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker9af723c2014-05-01 13:03:14 +0200376static uint32_t FT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100377#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker9af723c2014-05-01 13:03:14 +0200378static uint32_t FT1[256];
379static uint32_t FT2[256];
380static uint32_t FT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100381#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100382#endif /* !defined(MBEDTLS_AES_ENCRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
384/*
385 * Reverse S-box & tables
386 */
Dave Rodgman15cd28a2023-06-27 18:27:31 +0100387#if !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT))
Paul Bakker5121ce52009-01-03 21:22:43 +0000388static unsigned char RSb[256];
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100389#endif /* !(defined(MBEDTLS_AES_SETKEY_ENC_ALT) && defined(MBEDTLS_AES_DECRYPT_ALT)) */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100390
391#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000392static uint32_t RT0[256];
Hanno Beckerad049a92017-06-19 16:31:54 +0100393#if !defined(MBEDTLS_AES_FEWER_TABLES)
Paul Bakker5c2364c2012-10-01 14:41:15 +0000394static uint32_t RT1[256];
395static uint32_t RT2[256];
396static uint32_t RT3[256];
Hanno Becker177d3cf2017-06-07 15:52:48 +0100397#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgman710e3c62023-06-29 11:58:04 +0100398#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
Dave Rodgman8c753f92023-06-27 18:16:13 +0100400#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Paul Bakker5121ce52009-01-03 21:22:43 +0000401/*
402 * Round constants
403 */
Paul Bakker5c2364c2012-10-01 14:41:15 +0000404static uint32_t RCON[10];
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
406/*
407 * Tables generation code
408 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100409#define ROTL8(x) (((x) << 8) & 0xFFFFFFFF) | ((x) >> 24)
410#define XTIME(x) (((x) << 1) ^ (((x) & 0x80) ? 0x1B : 0x00))
411#define MUL(x, y) (((x) && (y)) ? pow[(log[(x)]+log[(y)]) % 255] : 0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
413static int aes_init_done = 0;
414
Gilles Peskine449bd832023-01-11 14:50:10 +0100415static void aes_gen_tables(void)
Paul Bakker5121ce52009-01-03 21:22:43 +0000416{
Yanray Wangfe944ce2023-06-26 18:16:01 +0800417 int i;
418 uint8_t x, y, z;
Yanray Wang5c86b172023-06-26 16:54:52 +0800419 uint8_t pow[256];
420 uint8_t log[256];
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
422 /*
423 * compute pow and log tables over GF(2^8)
424 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100425 for (i = 0, x = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 pow[i] = x;
Yanray Wang5c86b172023-06-26 16:54:52 +0800427 log[x] = (uint8_t) i;
Yanray Wangfe944ce2023-06-26 18:16:01 +0800428 x ^= XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 }
430
431 /*
432 * calculate the round constants
433 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 for (i = 0, x = 1; i < 10; i++) {
Yanray Wangfe944ce2023-06-26 18:16:01 +0800435 RCON[i] = x;
436 x = XTIME(x);
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 }
438
439 /*
440 * generate the forward and reverse S-boxes
441 */
442 FSb[0x00] = 0x63;
443 RSb[0x63] = 0x00;
444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 for (i = 1; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 x = pow[255 - log[i]];
447
Yanray Wangfe944ce2023-06-26 18:16:01 +0800448 y = x; y = (y << 1) | (y >> 7);
449 x ^= y; y = (y << 1) | (y >> 7);
450 x ^= y; y = (y << 1) | (y >> 7);
451 x ^= y; y = (y << 1) | (y >> 7);
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 x ^= y ^ 0x63;
453
Yanray Wangfe944ce2023-06-26 18:16:01 +0800454 FSb[i] = x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 RSb[x] = (unsigned char) i;
456 }
457
458 /*
459 * generate the forward and reverse tables
460 */
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000462 x = FSb[i];
Yanray Wangfe944ce2023-06-26 18:16:01 +0800463 y = XTIME(x);
464 z = y ^ x;
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 FT0[i] = ((uint32_t) y) ^
467 ((uint32_t) x << 8) ^
468 ((uint32_t) x << 16) ^
469 ((uint32_t) z << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
Hanno Beckerad049a92017-06-19 16:31:54 +0100471#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100472 FT1[i] = ROTL8(FT0[i]);
473 FT2[i] = ROTL8(FT1[i]);
474 FT3[i] = ROTL8(FT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100475#endif /* !MBEDTLS_AES_FEWER_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000476
477 x = RSb[i];
478
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100479#if !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
481 ((uint32_t) MUL(0x09, x) << 8) ^
482 ((uint32_t) MUL(0x0D, x) << 16) ^
483 ((uint32_t) MUL(0x0B, x) << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
Hanno Beckerad049a92017-06-19 16:31:54 +0100485#if !defined(MBEDTLS_AES_FEWER_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100486 RT1[i] = ROTL8(RT0[i]);
487 RT2[i] = ROTL8(RT1[i]);
488 RT3[i] = ROTL8(RT2[i]);
Hanno Becker177d3cf2017-06-07 15:52:48 +0100489#endif /* !MBEDTLS_AES_FEWER_TABLES */
Dave Rodgmanad4e76b2023-06-27 19:20:27 +0100490#endif /* !defined(MBEDTLS_AES_DECRYPT_ALT) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) */
Paul Bakker5121ce52009-01-03 21:22:43 +0000491 }
492}
493
Dave Rodgman8c753f92023-06-27 18:16:13 +0100494#endif /* !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
495
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200496#undef ROTL8
497
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498#endif /* MBEDTLS_AES_ROM_TABLES */
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
Hanno Beckerad049a92017-06-19 16:31:54 +0100500#if defined(MBEDTLS_AES_FEWER_TABLES)
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200501
Gilles Peskine449bd832023-01-11 14:50:10 +0100502#define ROTL8(x) ((uint32_t) ((x) << 8) + (uint32_t) ((x) >> 24))
503#define ROTL16(x) ((uint32_t) ((x) << 16) + (uint32_t) ((x) >> 16))
504#define ROTL24(x) ((uint32_t) ((x) << 24) + (uint32_t) ((x) >> 8))
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200505
506#define AES_RT0(idx) RT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100507#define AES_RT1(idx) ROTL8(RT0[idx])
508#define AES_RT2(idx) ROTL16(RT0[idx])
509#define AES_RT3(idx) ROTL24(RT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200510
511#define AES_FT0(idx) FT0[idx]
Gilles Peskine449bd832023-01-11 14:50:10 +0100512#define AES_FT1(idx) ROTL8(FT0[idx])
513#define AES_FT2(idx) ROTL16(FT0[idx])
514#define AES_FT3(idx) ROTL24(FT0[idx])
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200515
Hanno Becker177d3cf2017-06-07 15:52:48 +0100516#else /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200517
518#define AES_RT0(idx) RT0[idx]
519#define AES_RT1(idx) RT1[idx]
520#define AES_RT2(idx) RT2[idx]
521#define AES_RT3(idx) RT3[idx]
522
523#define AES_FT0(idx) FT0[idx]
524#define AES_FT1(idx) FT1[idx]
525#define AES_FT2(idx) FT2[idx]
526#define AES_FT3(idx) FT3[idx]
527
Hanno Becker177d3cf2017-06-07 15:52:48 +0100528#endif /* MBEDTLS_AES_FEWER_TABLES */
Jussi Kivilinna2fd1bb82015-11-12 16:38:31 +0200529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530void mbedtls_aes_init(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200531{
Gilles Peskine449bd832023-01-11 14:50:10 +0100532 memset(ctx, 0, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200533}
534
Gilles Peskine449bd832023-01-11 14:50:10 +0100535void mbedtls_aes_free(mbedtls_aes_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200536{
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200538 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200540
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_aes_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200542}
543
Jaeden Amero9366feb2018-05-29 18:55:17 +0100544#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100545void mbedtls_aes_xts_init(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100546{
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 mbedtls_aes_init(&ctx->crypt);
548 mbedtls_aes_init(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100549}
550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551void mbedtls_aes_xts_free(mbedtls_aes_xts_context *ctx)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100552{
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 if (ctx == NULL) {
Manuel Pégourié-Gonnard44c5d582018-12-10 16:56:14 +0100554 return;
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 }
Simon Butcher5201e412018-12-06 17:40:14 +0000556
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 mbedtls_aes_free(&ctx->crypt);
558 mbedtls_aes_free(&ctx->tweak);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100559}
560#endif /* MBEDTLS_CIPHER_MODE_XTS */
561
Gilles Peskine0de8f852023-03-16 17:14:59 +0100562/* Some implementations need the round keys to be aligned.
563 * Return an offset to be added to buf, such that (buf + offset) is
564 * correctly aligned.
565 * Note that the offset is in units of elements of buf, i.e. 32-bit words,
566 * i.e. an offset of 1 means 4 bytes and so on.
567 */
568#if (defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)) || \
Gilles Peskine9c682e72023-03-16 17:21:33 +0100569 (defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100570#define MAY_NEED_TO_ALIGN
571#endif
Dave Rodgman28a539a2023-06-27 18:22:34 +0100572
Dave Rodgman2fd8c2c2023-06-27 21:03:31 +0100573#if defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
574 !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine0de8f852023-03-16 17:14:59 +0100575static unsigned mbedtls_aes_rk_offset(uint32_t *buf)
576{
577#if defined(MAY_NEED_TO_ALIGN)
578 int align_16_bytes = 0;
579
580#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
581 if (aes_padlock_ace == -1) {
582 aes_padlock_ace = mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE);
583 }
584 if (aes_padlock_ace) {
585 align_16_bytes = 1;
586 }
587#endif
588
Gilles Peskine9c682e72023-03-16 17:21:33 +0100589#if defined(MBEDTLS_AESNI_C) && MBEDTLS_AESNI_HAVE_CODE == 2
Gilles Peskine0de8f852023-03-16 17:14:59 +0100590 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
591 align_16_bytes = 1;
592 }
593#endif
594
595 if (align_16_bytes) {
596 /* These implementations needs 16-byte alignment
597 * for the round key array. */
598 unsigned delta = ((uintptr_t) buf & 0x0000000fU) / 4;
599 if (delta == 0) {
600 return 0;
601 } else {
602 return 4 - delta; // 16 bytes = 4 uint32_t
603 }
604 }
605#else /* MAY_NEED_TO_ALIGN */
606 (void) buf;
607#endif /* MAY_NEED_TO_ALIGN */
608
609 return 0;
610}
Dave Rodgmanafe85db2023-06-29 12:07:11 +0100611#endif /* defined(MAY_NEED_TO_ALIGN) || !defined(MBEDTLS_AES_SETKEY_DEC_ALT) || \
612 !defined(MBEDTLS_AES_SETKEY_ENC_ALT) */
Gilles Peskine0de8f852023-03-16 17:14:59 +0100613
Paul Bakker5121ce52009-01-03 21:22:43 +0000614/*
615 * AES key schedule (encryption)
616 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200617#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100618int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
619 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000620{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800621#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Paul Bakker23986e52011-04-24 08:57:21 +0000622 unsigned int i;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800623#endif
Paul Bakker5c2364c2012-10-01 14:41:15 +0000624 uint32_t *RK;
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
Gilles Peskine449bd832023-01-11 14:50:10 +0100626 switch (keybits) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 case 128: ctx->nr = 10; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800628#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 case 192: ctx->nr = 12; break;
630 case 256: ctx->nr = 14; break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800631#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Gilles Peskine449bd832023-01-11 14:50:10 +0100632 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Paul Bakker5121ce52009-01-03 21:22:43 +0000633 }
634
Simon Butcher5201e412018-12-06 17:40:14 +0000635#if !defined(MBEDTLS_AES_ROM_TABLES)
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 if (aes_init_done == 0) {
Simon Butcher5201e412018-12-06 17:40:14 +0000637 aes_gen_tables();
638 aes_init_done = 1;
Simon Butcher5201e412018-12-06 17:40:14 +0000639 }
640#endif
641
Gilles Peskine0de8f852023-03-16 17:14:59 +0100642 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100643 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100645#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
647 return mbedtls_aesni_setkey_enc((unsigned char *) RK, key, keybits);
648 }
Manuel Pégourié-Gonnard47a35362013-12-28 20:45:04 +0100649#endif
650
Jerry Yu3f2fb712023-01-10 17:05:42 +0800651#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
652 if (mbedtls_aesce_has_support()) {
653 return mbedtls_aesce_setkey_enc((unsigned char *) RK, key, keybits);
654 }
655#endif
656
Jerry Yu29c91ba2023-08-04 11:02:04 +0800657#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 for (i = 0; i < (keybits >> 5); i++) {
659 RK[i] = MBEDTLS_GET_UINT32_LE(key, i << 2);
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 }
661
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 switch (ctx->nr) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 case 10:
664
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 for (i = 0; i < 10; i++, RK += 4) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000666 RK[4] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[3])]) ^
668 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[3])] << 8) ^
669 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[3])] << 16) ^
670 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[3])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672 RK[5] = RK[1] ^ RK[4];
673 RK[6] = RK[2] ^ RK[5];
674 RK[7] = RK[3] ^ RK[6];
675 }
676 break;
677
Arto Kinnunen732ca322023-04-14 14:26:10 +0800678#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +0000679 case 12:
680
Gilles Peskine449bd832023-01-11 14:50:10 +0100681 for (i = 0; i < 8; i++, RK += 6) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000682 RK[6] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[5])]) ^
684 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[5])] << 8) ^
685 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[5])] << 16) ^
686 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[5])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000687
688 RK[7] = RK[1] ^ RK[6];
689 RK[8] = RK[2] ^ RK[7];
690 RK[9] = RK[3] ^ RK[8];
691 RK[10] = RK[4] ^ RK[9];
692 RK[11] = RK[5] ^ RK[10];
693 }
694 break;
695
696 case 14:
697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 for (i = 0; i < 7; i++, RK += 8) {
Paul Bakker5121ce52009-01-03 21:22:43 +0000699 RK[8] = RK[0] ^ RCON[i] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[7])]) ^
701 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[7])] << 8) ^
702 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[7])] << 16) ^
703 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[7])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000704
705 RK[9] = RK[1] ^ RK[8];
706 RK[10] = RK[2] ^ RK[9];
707 RK[11] = RK[3] ^ RK[10];
708
709 RK[12] = RK[4] ^
Gilles Peskine449bd832023-01-11 14:50:10 +0100710 ((uint32_t) FSb[MBEDTLS_BYTE_0(RK[11])]) ^
711 ((uint32_t) FSb[MBEDTLS_BYTE_1(RK[11])] << 8) ^
712 ((uint32_t) FSb[MBEDTLS_BYTE_2(RK[11])] << 16) ^
713 ((uint32_t) FSb[MBEDTLS_BYTE_3(RK[11])] << 24);
Paul Bakker5121ce52009-01-03 21:22:43 +0000714
715 RK[13] = RK[5] ^ RK[12];
716 RK[14] = RK[6] ^ RK[13];
717 RK[15] = RK[7] ^ RK[14];
718 }
719 break;
Arto Kinnunen732ca322023-04-14 14:26:10 +0800720#endif /* !MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH */
Paul Bakker5121ce52009-01-03 21:22:43 +0000721 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000722
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 return 0;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800724#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakker5121ce52009-01-03 21:22:43 +0000725}
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200726#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
728/*
729 * AES key schedule (decryption)
730 */
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200731#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100732int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
733 unsigned int keybits)
Paul Bakker5121ce52009-01-03 21:22:43 +0000734{
Jerry Yu29c91ba2023-08-04 11:02:04 +0800735#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
736 int i, j;
737 uint32_t *SK;
738#endif
739 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200740 mbedtls_aes_context cty;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000741 uint32_t *RK;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800742
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200743
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 mbedtls_aes_init(&cty);
Paul Bakker5121ce52009-01-03 21:22:43 +0000745
Gilles Peskine0de8f852023-03-16 17:14:59 +0100746 ctx->rk_offset = mbedtls_aes_rk_offset(ctx->buf);
Werner Lewisdd76ef32022-05-30 12:00:21 +0100747 RK = ctx->buf + ctx->rk_offset;
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Manuel Pégourié-Gonnardb8186a52015-06-18 14:58:58 +0200749 /* Also checks keybits */
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 if ((ret = mbedtls_aes_setkey_enc(&cty, key, keybits)) != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200751 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +0100752 }
Paul Bakker2b222c82009-07-27 21:03:45 +0000753
Manuel Pégourié-Gonnardafd5a082014-05-28 21:52:59 +0200754 ctx->nr = cty.nr;
755
Gilles Peskine9af58cd2023-03-10 22:29:32 +0100756#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
758 mbedtls_aesni_inverse_key((unsigned char *) RK,
759 (const unsigned char *) (cty.buf + cty.rk_offset), ctx->nr);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200760 goto exit;
Manuel Pégourié-Gonnard01e31bb2013-12-28 15:58:30 +0100761 }
762#endif
763
Jerry Yue096da12023-01-10 17:07:01 +0800764#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
765 if (mbedtls_aesce_has_support()) {
766 mbedtls_aesce_inverse_key(
767 (unsigned char *) RK,
768 (const unsigned char *) (cty.buf + cty.rk_offset),
769 ctx->nr);
770 goto exit;
771 }
772#endif
773
Jerry Yu29c91ba2023-08-04 11:02:04 +0800774#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Werner Lewisdd76ef32022-05-30 12:00:21 +0100775 SK = cty.buf + cty.rk_offset + cty.nr * 4;
Paul Bakker5121ce52009-01-03 21:22:43 +0000776
777 *RK++ = *SK++;
778 *RK++ = *SK++;
779 *RK++ = *SK++;
780 *RK++ = *SK++;
781
Gilles Peskine449bd832023-01-11 14:50:10 +0100782 for (i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8) {
783 for (j = 0; j < 4; j++, SK++) {
784 *RK++ = AES_RT0(FSb[MBEDTLS_BYTE_0(*SK)]) ^
785 AES_RT1(FSb[MBEDTLS_BYTE_1(*SK)]) ^
786 AES_RT2(FSb[MBEDTLS_BYTE_2(*SK)]) ^
787 AES_RT3(FSb[MBEDTLS_BYTE_3(*SK)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 }
789 }
790
791 *RK++ = *SK++;
792 *RK++ = *SK++;
793 *RK++ = *SK++;
794 *RK++ = *SK++;
Jerry Yu29c91ba2023-08-04 11:02:04 +0800795#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200796exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 mbedtls_aes_free(&cty);
Paul Bakker2b222c82009-07-27 21:03:45 +0000798
Gilles Peskine449bd832023-01-11 14:50:10 +0100799 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000800}
gabor-mezei-arm95db3012020-10-26 11:35:23 +0100801#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
Jaeden Amero9366feb2018-05-29 18:55:17 +0100802
803#if defined(MBEDTLS_CIPHER_MODE_XTS)
Gilles Peskine449bd832023-01-11 14:50:10 +0100804static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
805 unsigned int keybits,
806 const unsigned char **key1,
807 unsigned int *key1bits,
808 const unsigned char **key2,
809 unsigned int *key2bits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100810{
811 const unsigned int half_keybits = keybits / 2;
812 const unsigned int half_keybytes = half_keybits / 8;
813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 switch (keybits) {
Jaeden Amero9366feb2018-05-29 18:55:17 +0100815 case 256: break;
816 case 512: break;
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 default: return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100818 }
819
820 *key1bits = half_keybits;
821 *key2bits = half_keybits;
822 *key1 = &key[0];
823 *key2 = &key[half_keybytes];
824
825 return 0;
826}
827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828int mbedtls_aes_xts_setkey_enc(mbedtls_aes_xts_context *ctx,
829 const unsigned char *key,
830 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100831{
Janos Follath24eed8d2019-11-22 13:21:35 +0000832 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100833 const unsigned char *key1, *key2;
834 unsigned int key1bits, key2bits;
835
Gilles Peskine449bd832023-01-11 14:50:10 +0100836 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
837 &key2, &key2bits);
838 if (ret != 0) {
839 return ret;
840 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100841
842 /* Set the tweak key. Always set tweak key for the encryption mode. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100843 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
844 if (ret != 0) {
845 return ret;
846 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100847
848 /* Set crypt key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 return mbedtls_aes_setkey_enc(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100850}
851
Gilles Peskine449bd832023-01-11 14:50:10 +0100852int mbedtls_aes_xts_setkey_dec(mbedtls_aes_xts_context *ctx,
853 const unsigned char *key,
854 unsigned int keybits)
Jaeden Amero9366feb2018-05-29 18:55:17 +0100855{
Janos Follath24eed8d2019-11-22 13:21:35 +0000856 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amero9366feb2018-05-29 18:55:17 +0100857 const unsigned char *key1, *key2;
858 unsigned int key1bits, key2bits;
859
Gilles Peskine449bd832023-01-11 14:50:10 +0100860 ret = mbedtls_aes_xts_decode_keys(key, keybits, &key1, &key1bits,
861 &key2, &key2bits);
862 if (ret != 0) {
863 return ret;
864 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100865
866 /* Set the tweak key. Always set tweak key for encryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 ret = mbedtls_aes_setkey_enc(&ctx->tweak, key2, key2bits);
868 if (ret != 0) {
869 return ret;
870 }
Jaeden Amero9366feb2018-05-29 18:55:17 +0100871
872 /* Set crypt key for decryption. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 return mbedtls_aes_setkey_dec(&ctx->crypt, key1, key1bits);
Jaeden Amero9366feb2018-05-29 18:55:17 +0100874}
875#endif /* MBEDTLS_CIPHER_MODE_XTS */
876
Gilles Peskine449bd832023-01-11 14:50:10 +0100877#define AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Joe Subbianicd84d762021-07-08 14:59:52 +0100878 do \
879 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100880 (X0) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y0)) ^ \
881 AES_FT1(MBEDTLS_BYTE_1(Y1)) ^ \
882 AES_FT2(MBEDTLS_BYTE_2(Y2)) ^ \
883 AES_FT3(MBEDTLS_BYTE_3(Y3)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100884 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100885 (X1) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y1)) ^ \
886 AES_FT1(MBEDTLS_BYTE_1(Y2)) ^ \
887 AES_FT2(MBEDTLS_BYTE_2(Y3)) ^ \
888 AES_FT3(MBEDTLS_BYTE_3(Y0)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100889 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 (X2) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y2)) ^ \
891 AES_FT1(MBEDTLS_BYTE_1(Y3)) ^ \
892 AES_FT2(MBEDTLS_BYTE_2(Y0)) ^ \
893 AES_FT3(MBEDTLS_BYTE_3(Y1)); \
Joe Subbianicd84d762021-07-08 14:59:52 +0100894 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100895 (X3) = *RK++ ^ AES_FT0(MBEDTLS_BYTE_0(Y3)) ^ \
896 AES_FT1(MBEDTLS_BYTE_1(Y0)) ^ \
897 AES_FT2(MBEDTLS_BYTE_2(Y1)) ^ \
898 AES_FT3(MBEDTLS_BYTE_3(Y2)); \
899 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
Gilles Peskine449bd832023-01-11 14:50:10 +0100901#define AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
Hanno Becker1eeca412018-10-15 12:01:35 +0100902 do \
903 { \
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 (X0) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y0)) ^ \
905 AES_RT1(MBEDTLS_BYTE_1(Y3)) ^ \
906 AES_RT2(MBEDTLS_BYTE_2(Y2)) ^ \
907 AES_RT3(MBEDTLS_BYTE_3(Y1)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100908 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 (X1) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y1)) ^ \
910 AES_RT1(MBEDTLS_BYTE_1(Y0)) ^ \
911 AES_RT2(MBEDTLS_BYTE_2(Y3)) ^ \
912 AES_RT3(MBEDTLS_BYTE_3(Y2)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100913 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100914 (X2) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y2)) ^ \
915 AES_RT1(MBEDTLS_BYTE_1(Y1)) ^ \
916 AES_RT2(MBEDTLS_BYTE_2(Y0)) ^ \
917 AES_RT3(MBEDTLS_BYTE_3(Y3)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100918 \
Gilles Peskine449bd832023-01-11 14:50:10 +0100919 (X3) = *RK++ ^ AES_RT0(MBEDTLS_BYTE_0(Y3)) ^ \
920 AES_RT1(MBEDTLS_BYTE_1(Y2)) ^ \
921 AES_RT2(MBEDTLS_BYTE_2(Y1)) ^ \
922 AES_RT3(MBEDTLS_BYTE_3(Y0)); \
923 } while (0)
Paul Bakker5121ce52009-01-03 21:22:43 +0000924
925/*
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200926 * AES-ECB block encryption
927 */
928#if !defined(MBEDTLS_AES_ENCRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100929int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
930 const unsigned char input[16],
931 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200932{
933 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100934 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200936 uint32_t X[4];
937 uint32_t Y[4];
938 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200939
Gilles Peskine449bd832023-01-11 14:50:10 +0100940 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
941 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
942 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
943 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
946 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]);
947 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 +0200948 }
949
Gilles Peskine449bd832023-01-11 14:50:10 +0100950 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 +0200951
Gilles Peskine5197c662020-08-26 17:03:24 +0200952 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
954 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
955 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
956 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200957
Gilles Peskine5197c662020-08-26 17:03:24 +0200958 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
960 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
961 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
962 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200963
Gilles Peskine5197c662020-08-26 17:03:24 +0200964 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
966 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
967 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
968 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200969
Gilles Peskine5197c662020-08-26 17:03:24 +0200970 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 ((uint32_t) FSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
972 ((uint32_t) FSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
973 ((uint32_t) FSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
974 ((uint32_t) FSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200975
Gilles Peskine449bd832023-01-11 14:50:10 +0100976 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
977 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
978 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
979 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +0000980
Gilles Peskine449bd832023-01-11 14:50:10 +0100981 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -0500982
Gilles Peskine449bd832023-01-11 14:50:10 +0100983 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200984}
985#endif /* !MBEDTLS_AES_ENCRYPT_ALT */
986
987/*
988 * AES-ECB block decryption
989 */
990#if !defined(MBEDTLS_AES_DECRYPT_ALT)
Gilles Peskine449bd832023-01-11 14:50:10 +0100991int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
992 const unsigned char input[16],
993 unsigned char output[16])
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +0200994{
995 int i;
Werner Lewisdd76ef32022-05-30 12:00:21 +0100996 uint32_t *RK = ctx->buf + ctx->rk_offset;
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 struct {
Gilles Peskine5197c662020-08-26 17:03:24 +0200998 uint32_t X[4];
999 uint32_t Y[4];
1000 } t;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001001
Gilles Peskine449bd832023-01-11 14:50:10 +01001002 t.X[0] = MBEDTLS_GET_UINT32_LE(input, 0); t.X[0] ^= *RK++;
1003 t.X[1] = MBEDTLS_GET_UINT32_LE(input, 4); t.X[1] ^= *RK++;
1004 t.X[2] = MBEDTLS_GET_UINT32_LE(input, 8); t.X[2] ^= *RK++;
1005 t.X[3] = MBEDTLS_GET_UINT32_LE(input, 12); t.X[3] ^= *RK++;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001006
Gilles Peskine449bd832023-01-11 14:50:10 +01001007 for (i = (ctx->nr >> 1) - 1; i > 0; i--) {
1008 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]);
1009 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 +02001010 }
1011
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 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 +02001013
Gilles Peskine5197c662020-08-26 17:03:24 +02001014 t.X[0] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[0])]) ^
1016 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[3])] << 8) ^
1017 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[2])] << 16) ^
1018 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[1])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001019
Gilles Peskine5197c662020-08-26 17:03:24 +02001020 t.X[1] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001021 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[1])]) ^
1022 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[0])] << 8) ^
1023 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[3])] << 16) ^
1024 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[2])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001025
Gilles Peskine5197c662020-08-26 17:03:24 +02001026 t.X[2] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[2])]) ^
1028 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[1])] << 8) ^
1029 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[0])] << 16) ^
1030 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[3])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001031
Gilles Peskine5197c662020-08-26 17:03:24 +02001032 t.X[3] = *RK++ ^ \
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 ((uint32_t) RSb[MBEDTLS_BYTE_0(t.Y[3])]) ^
1034 ((uint32_t) RSb[MBEDTLS_BYTE_1(t.Y[2])] << 8) ^
1035 ((uint32_t) RSb[MBEDTLS_BYTE_2(t.Y[1])] << 16) ^
1036 ((uint32_t) RSb[MBEDTLS_BYTE_3(t.Y[0])] << 24);
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001037
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 MBEDTLS_PUT_UINT32_LE(t.X[0], output, 0);
1039 MBEDTLS_PUT_UINT32_LE(t.X[1], output, 4);
1040 MBEDTLS_PUT_UINT32_LE(t.X[2], output, 8);
1041 MBEDTLS_PUT_UINT32_LE(t.X[3], output, 12);
Andres AGf5bf7182017-03-03 14:09:56 +00001042
Gilles Peskine449bd832023-01-11 14:50:10 +01001043 mbedtls_platform_zeroize(&t, sizeof(t));
Andrzej Kurek96ae5cd2019-11-12 03:05:51 -05001044
Gilles Peskine449bd832023-01-11 14:50:10 +01001045 return 0;
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001046}
1047#endif /* !MBEDTLS_AES_DECRYPT_ALT */
1048
Gilles Peskine0de8f852023-03-16 17:14:59 +01001049#if defined(MAY_NEED_TO_ALIGN)
Gilles Peskine148cad12023-03-16 13:08:42 +01001050/* VIA Padlock and our intrinsics-based implementation of AESNI require
1051 * the round keys to be aligned on a 16-byte boundary. We take care of this
1052 * before creating them, but the AES context may have moved (this can happen
1053 * if the library is called from a language with managed memory), and in later
1054 * calls it might have a different alignment with respect to 16-byte memory.
1055 * So we may need to realign.
1056 */
1057static void aes_maybe_realign(mbedtls_aes_context *ctx)
1058{
Gilles Peskine0de8f852023-03-16 17:14:59 +01001059 unsigned new_offset = mbedtls_aes_rk_offset(ctx->buf);
1060 if (new_offset != ctx->rk_offset) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001061 memmove(ctx->buf + new_offset, // new address
1062 ctx->buf + ctx->rk_offset, // current address
1063 (ctx->nr + 1) * 16); // number of round keys * bytes per rk
1064 ctx->rk_offset = new_offset;
1065 }
1066}
1067#endif
1068
Manuel Pégourié-Gonnard31993f22015-05-12 15:41:08 +02001069/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001070 * AES-ECB block encryption/decryption
1071 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001072int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
1073 int mode,
1074 const unsigned char input[16],
1075 unsigned char output[16])
Paul Bakker5121ce52009-01-03 21:22:43 +00001076{
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001078 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 }
Manuel Pégourié-Gonnard1aca2602018-12-12 12:56:55 +01001080
Gilles Peskine0de8f852023-03-16 17:14:59 +01001081#if defined(MAY_NEED_TO_ALIGN)
1082 aes_maybe_realign(ctx);
1083#endif
1084
Gilles Peskine9af58cd2023-03-10 22:29:32 +01001085#if defined(MBEDTLS_AESNI_HAVE_CODE)
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1087 return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
1088 }
Manuel Pégourié-Gonnard5b685652013-12-18 11:45:21 +01001089#endif
1090
Jerry Yu2bb3d812023-01-10 17:38:26 +08001091#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1092 if (mbedtls_aesce_has_support()) {
1093 return mbedtls_aesce_crypt_ecb(ctx, mode, input, output);
1094 }
1095#endif
1096
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001098 if (aes_padlock_ace > 0) {
Gilles Peskine148cad12023-03-16 13:08:42 +01001099 return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
Paul Bakker5121ce52009-01-03 21:22:43 +00001100 }
1101#endif
1102
Jerry Yu29c91ba2023-08-04 11:02:04 +08001103#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
Gilles Peskine449bd832023-01-11 14:50:10 +01001104 if (mode == MBEDTLS_AES_ENCRYPT) {
1105 return mbedtls_internal_aes_encrypt(ctx, input, output);
1106 } else {
1107 return mbedtls_internal_aes_decrypt(ctx, input, output);
1108 }
Jerry Yu29c91ba2023-08-04 11:02:04 +08001109#endif
1110
Paul Bakker5121ce52009-01-03 21:22:43 +00001111}
1112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113#if defined(MBEDTLS_CIPHER_MODE_CBC)
Dave Rodgmand05e7f12023-06-14 18:58:48 +01001114
Paul Bakker5121ce52009-01-03 21:22:43 +00001115/*
1116 * AES-CBC buffer encryption/decryption
1117 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001118int mbedtls_aes_crypt_cbc(mbedtls_aes_context *ctx,
1119 int mode,
1120 size_t length,
1121 unsigned char iv[16],
1122 const unsigned char *input,
1123 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001124{
Gilles Peskine7820a572021-07-07 21:08:28 +02001125 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5121ce52009-01-03 21:22:43 +00001126 unsigned char temp[16];
1127
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001129 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 }
Manuel Pégourié-Gonnard3178d1a2018-12-12 13:05:00 +01001131
Gilles Peskine449bd832023-01-11 14:50:10 +01001132 if (length % 16) {
1133 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
1134 }
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 if (aes_padlock_ace > 0) {
1138 if (mbedtls_padlock_xcryptcbc(ctx, mode, length, iv, input, output) == 0) {
1139 return 0;
1140 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001141
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001142 // If padlock data misaligned, we just fall back to
1143 // unaccelerated mode
1144 //
Paul Bakker5121ce52009-01-03 21:22:43 +00001145 }
1146#endif
1147
Dave Rodgman906c63c2023-06-14 17:53:51 +01001148 const unsigned char *ivp = iv;
1149
Gilles Peskine449bd832023-01-11 14:50:10 +01001150 if (mode == MBEDTLS_AES_DECRYPT) {
1151 while (length > 0) {
1152 memcpy(temp, input, 16);
1153 ret = mbedtls_aes_crypt_ecb(ctx, mode, input, output);
1154 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001155 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 }
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001157 /* Avoid using the NEON implementation of mbedtls_xor. Because of the dependency on
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001158 * the result for the next block in CBC, and the cost of transferring that data from
1159 * NEON registers, NEON is slower on aarch64. */
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001160 mbedtls_xor_no_simd(output, output, iv, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001161
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 memcpy(iv, temp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001163
1164 input += 16;
1165 output += 16;
1166 length -= 16;
1167 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001168 } else {
1169 while (length > 0) {
Dave Rodgmana0b166e2023-06-15 18:44:16 +01001170 mbedtls_xor_no_simd(output, input, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001171
Gilles Peskine449bd832023-01-11 14:50:10 +01001172 ret = mbedtls_aes_crypt_ecb(ctx, mode, output, output);
1173 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001174 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001176 ivp = output;
Paul Bakker5121ce52009-01-03 21:22:43 +00001177
1178 input += 16;
1179 output += 16;
1180 length -= 16;
1181 }
Dave Rodgman906c63c2023-06-14 17:53:51 +01001182 memcpy(iv, ivp, 16);
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001184 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001185
Gilles Peskine7820a572021-07-07 21:08:28 +02001186exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001187 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001188}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001190
Aorimn5f778012016-06-09 23:22:58 +02001191#if defined(MBEDTLS_CIPHER_MODE_XTS)
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001192
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001193typedef unsigned char mbedtls_be128[16];
1194
1195/*
1196 * GF(2^128) multiplication function
1197 *
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001198 * This function multiplies a field element by x in the polynomial field
1199 * representation. It uses 64-bit word operations to gain speed but compensates
Shaun Case8b0ecbc2021-12-20 21:14:10 -08001200 * for machine endianness and hence works correctly on both big and little
Jaeden Amero5f0b06a2018-05-31 09:23:32 +01001201 * endian machines.
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001202 */
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001203#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001204MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgman4ad81cc2023-06-16 15:04:04 +01001205#endif
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001206static inline void mbedtls_gf128mul_x_ble(unsigned char r[16],
Dave Rodgman2dd15b32023-06-15 20:27:53 +01001207 const unsigned char x[16])
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001208{
1209 uint64_t a, b, ra, rb;
1210
Gilles Peskine449bd832023-01-11 14:50:10 +01001211 a = MBEDTLS_GET_UINT64_LE(x, 0);
1212 b = MBEDTLS_GET_UINT64_LE(x, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001213
Gilles Peskine449bd832023-01-11 14:50:10 +01001214 ra = (a << 1) ^ 0x0087 >> (8 - ((b >> 63) << 3));
1215 rb = (a >> 63) | (b << 1);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001216
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 MBEDTLS_PUT_UINT64_LE(ra, r, 0);
1218 MBEDTLS_PUT_UINT64_LE(rb, r, 8);
Jaeden Amero010c2cb2018-05-29 17:00:47 +01001219}
1220
Aorimn5f778012016-06-09 23:22:58 +02001221/*
1222 * AES-XTS buffer encryption/decryption
Dave Rodgman6cfd9b52023-06-15 18:46:23 +01001223 *
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001224 * Use of MBEDTLS_OPTIMIZE_FOR_PERFORMANCE here and for mbedtls_gf128mul_x_ble()
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001225 * is a 3x performance improvement for gcc -Os, if we have hardware AES support.
Aorimn5f778012016-06-09 23:22:58 +02001226 */
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001227#if defined(MBEDTLS_AESCE_C) || defined(MBEDTLS_AESNI_C)
Dave Rodgman9bb7e6f2023-06-16 09:41:21 +01001228MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
Dave Rodgmanb2814bd2023-06-16 14:50:33 +01001229#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001230int mbedtls_aes_crypt_xts(mbedtls_aes_xts_context *ctx,
1231 int mode,
1232 size_t length,
1233 const unsigned char data_unit[16],
1234 const unsigned char *input,
1235 unsigned char *output)
Aorimn5f778012016-06-09 23:22:58 +02001236{
Janos Follath24eed8d2019-11-22 13:21:35 +00001237 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jaeden Amerod82cd862018-04-28 15:02:45 +01001238 size_t blocks = length / 16;
1239 size_t leftover = length % 16;
1240 unsigned char tweak[16];
1241 unsigned char prev_tweak[16];
1242 unsigned char tmp[16];
Aorimn5f778012016-06-09 23:22:58 +02001243
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001245 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001246 }
Manuel Pégourié-Gonnard191af132018-12-13 10:15:30 +01001247
Jaeden Amero8381fcb2018-10-11 12:06:15 +01001248 /* Data units must be at least 16 bytes long. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 if (length < 16) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001250 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 }
Aorimn5f778012016-06-09 23:22:58 +02001252
Jaeden Ameroa74faba2018-10-11 12:07:43 +01001253 /* NIST SP 800-38E disallows data units larger than 2**20 blocks. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 if (length > (1 << 20) * 16) {
Jaeden Amero0a8b0202018-05-30 15:36:06 +01001255 return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 }
Aorimn5f778012016-06-09 23:22:58 +02001257
Jaeden Amerod82cd862018-04-28 15:02:45 +01001258 /* Compute the tweak. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 ret = mbedtls_aes_crypt_ecb(&ctx->tweak, MBEDTLS_AES_ENCRYPT,
1260 data_unit, tweak);
1261 if (ret != 0) {
1262 return ret;
1263 }
Aorimn5f778012016-06-09 23:22:58 +02001264
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 while (blocks--) {
Dave Rodgman360e04f2023-06-09 17:18:32 +01001266 if (MBEDTLS_UNLIKELY(leftover && (mode == MBEDTLS_AES_DECRYPT) && blocks == 0)) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001267 /* We are on the last block in a decrypt operation that has
1268 * leftover bytes, so we need to use the next tweak for this block,
Tom Cosgrove1797b052022-12-04 17:19:59 +00001269 * and this tweak for the leftover bytes. Save the current tweak for
Jaeden Amerod82cd862018-04-28 15:02:45 +01001270 * the leftovers and then update the current tweak for use on this,
1271 * the last full block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 memcpy(prev_tweak, tweak, sizeof(tweak));
1273 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001274 }
1275
Gilles Peskine449bd832023-01-11 14:50:10 +01001276 mbedtls_xor(tmp, input, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001277
Gilles Peskine449bd832023-01-11 14:50:10 +01001278 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1279 if (ret != 0) {
1280 return ret;
1281 }
Jaeden Amerod82cd862018-04-28 15:02:45 +01001282
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 mbedtls_xor(output, tmp, tweak, 16);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001284
1285 /* Update the tweak for the next block. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001286 mbedtls_gf128mul_x_ble(tweak, tweak);
Jaeden Amerod82cd862018-04-28 15:02:45 +01001287
1288 output += 16;
1289 input += 16;
Aorimn5f778012016-06-09 23:22:58 +02001290 }
1291
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 if (leftover) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001293 /* If we are on the leftover bytes in a decrypt operation, we need to
1294 * use the previous tweak for these bytes (as saved in prev_tweak). */
1295 unsigned char *t = mode == MBEDTLS_AES_DECRYPT ? prev_tweak : tweak;
Aorimn5f778012016-06-09 23:22:58 +02001296
Jaeden Amerod82cd862018-04-28 15:02:45 +01001297 /* We are now on the final part of the data unit, which doesn't divide
1298 * evenly by 16. It's time for ciphertext stealing. */
1299 size_t i;
1300 unsigned char *prev_output = output - 16;
Aorimn5f778012016-06-09 23:22:58 +02001301
Jaeden Amerod82cd862018-04-28 15:02:45 +01001302 /* Copy ciphertext bytes from the previous block to our output for each
Dave Rodgman069e7f42022-11-24 19:37:26 +00001303 * byte of ciphertext we won't steal. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001304 for (i = 0; i < leftover; i++) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001305 output[i] = prev_output[i];
Aorimn5f778012016-06-09 23:22:58 +02001306 }
Aorimn5f778012016-06-09 23:22:58 +02001307
Dave Rodgman069e7f42022-11-24 19:37:26 +00001308 /* Copy the remainder of the input for this final round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 mbedtls_xor(tmp, input, t, leftover);
Dave Rodgmana8cf6072022-11-22 15:02:54 +00001310
Jaeden Amerod82cd862018-04-28 15:02:45 +01001311 /* Copy ciphertext bytes from the previous block for input in this
1312 * round. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 mbedtls_xor(tmp + i, prev_output + i, t + i, 16 - i);
Aorimn5f778012016-06-09 23:22:58 +02001314
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 ret = mbedtls_aes_crypt_ecb(&ctx->crypt, mode, tmp, tmp);
1316 if (ret != 0) {
Jaeden Amerod82cd862018-04-28 15:02:45 +01001317 return ret;
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 }
Aorimn5f778012016-06-09 23:22:58 +02001319
Jaeden Amerod82cd862018-04-28 15:02:45 +01001320 /* Write the result back to the previous block, overriding the previous
1321 * output we copied. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 mbedtls_xor(prev_output, tmp, t, 16);
Aorimn5f778012016-06-09 23:22:58 +02001323 }
1324
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 return 0;
Aorimn5f778012016-06-09 23:22:58 +02001326}
1327#endif /* MBEDTLS_CIPHER_MODE_XTS */
1328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001330/*
1331 * AES-CFB128 buffer encryption/decryption
1332 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001333int mbedtls_aes_crypt_cfb128(mbedtls_aes_context *ctx,
1334 int mode,
1335 size_t length,
1336 size_t *iv_off,
1337 unsigned char iv[16],
1338 const unsigned char *input,
1339 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +00001340{
Paul Bakker27fdf462011-06-09 13:55:13 +00001341 int c;
Gilles Peskine7820a572021-07-07 21:08:28 +02001342 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001343 size_t n;
1344
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001346 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 }
Manuel Pégourié-Gonnard1677cca2018-12-13 10:27:13 +01001348
1349 n = *iv_off;
Paul Bakker5121ce52009-01-03 21:22:43 +00001350
Gilles Peskine449bd832023-01-11 14:50:10 +01001351 if (n > 15) {
1352 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1353 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001354
Gilles Peskine449bd832023-01-11 14:50:10 +01001355 if (mode == MBEDTLS_AES_DECRYPT) {
1356 while (length--) {
1357 if (n == 0) {
1358 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1359 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001360 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001361 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001362 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001363
1364 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 *output++ = (unsigned char) (c ^ iv[n]);
Paul Bakker5121ce52009-01-03 21:22:43 +00001366 iv[n] = (unsigned char) c;
1367
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001369 }
Gilles Peskine449bd832023-01-11 14:50:10 +01001370 } else {
1371 while (length--) {
1372 if (n == 0) {
1373 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1374 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001375 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001377 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001378
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 iv[n] = *output++ = (unsigned char) (iv[n] ^ *input++);
Paul Bakker5121ce52009-01-03 21:22:43 +00001380
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 n = (n + 1) & 0x0F;
Paul Bakker5121ce52009-01-03 21:22:43 +00001382 }
1383 }
1384
1385 *iv_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001386 ret = 0;
Paul Bakkerf3ccc682010-03-18 21:21:02 +00001387
Gilles Peskine7820a572021-07-07 21:08:28 +02001388exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00001390}
Paul Bakker556efba2014-01-24 15:38:12 +01001391
1392/*
1393 * AES-CFB8 buffer encryption/decryption
1394 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001395int mbedtls_aes_crypt_cfb8(mbedtls_aes_context *ctx,
1396 int mode,
1397 size_t length,
1398 unsigned char iv[16],
1399 const unsigned char *input,
1400 unsigned char *output)
Paul Bakker556efba2014-01-24 15:38:12 +01001401{
Gilles Peskine7820a572021-07-07 21:08:28 +02001402 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker556efba2014-01-24 15:38:12 +01001403 unsigned char c;
1404 unsigned char ov[17];
1405
Gilles Peskine449bd832023-01-11 14:50:10 +01001406 if (mode != MBEDTLS_AES_ENCRYPT && mode != MBEDTLS_AES_DECRYPT) {
Tuvshinzaya Erdenekhuua8ef1562022-08-05 15:31:57 +01001407 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
Gilles Peskine449bd832023-01-11 14:50:10 +01001408 }
1409 while (length--) {
1410 memcpy(ov, iv, 16);
1411 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1412 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001413 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001414 }
Paul Bakker556efba2014-01-24 15:38:12 +01001415
Gilles Peskine449bd832023-01-11 14:50:10 +01001416 if (mode == MBEDTLS_AES_DECRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001417 ov[16] = *input;
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 }
Paul Bakker556efba2014-01-24 15:38:12 +01001419
Gilles Peskine449bd832023-01-11 14:50:10 +01001420 c = *output++ = (unsigned char) (iv[0] ^ *input++);
Paul Bakker556efba2014-01-24 15:38:12 +01001421
Gilles Peskine449bd832023-01-11 14:50:10 +01001422 if (mode == MBEDTLS_AES_ENCRYPT) {
Paul Bakker556efba2014-01-24 15:38:12 +01001423 ov[16] = c;
Gilles Peskine449bd832023-01-11 14:50:10 +01001424 }
Paul Bakker556efba2014-01-24 15:38:12 +01001425
Gilles Peskine449bd832023-01-11 14:50:10 +01001426 memcpy(iv, ov + 1, 16);
Paul Bakker556efba2014-01-24 15:38:12 +01001427 }
Gilles Peskine7820a572021-07-07 21:08:28 +02001428 ret = 0;
Paul Bakker556efba2014-01-24 15:38:12 +01001429
Gilles Peskine7820a572021-07-07 21:08:28 +02001430exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001431 return ret;
Paul Bakker556efba2014-01-24 15:38:12 +01001432}
Simon Butcher76a5b222018-04-22 22:57:27 +01001433#endif /* MBEDTLS_CIPHER_MODE_CFB */
1434
1435#if defined(MBEDTLS_CIPHER_MODE_OFB)
1436/*
1437 * AES-OFB (Output Feedback Mode) buffer encryption/decryption
1438 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001439int mbedtls_aes_crypt_ofb(mbedtls_aes_context *ctx,
1440 size_t length,
1441 size_t *iv_off,
1442 unsigned char iv[16],
1443 const unsigned char *input,
1444 unsigned char *output)
Simon Butcher76a5b222018-04-22 22:57:27 +01001445{
Simon Butcherad4e4932018-04-29 00:43:47 +01001446 int ret = 0;
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001447 size_t n;
1448
Manuel Pégourié-Gonnard8e41eb72018-12-13 11:00:56 +01001449 n = *iv_off;
Simon Butcher76a5b222018-04-22 22:57:27 +01001450
Gilles Peskine449bd832023-01-11 14:50:10 +01001451 if (n > 15) {
1452 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1453 }
Manuel Pégourié-Gonnard5b89c092018-12-18 10:03:30 +01001454
Gilles Peskine449bd832023-01-11 14:50:10 +01001455 while (length--) {
1456 if (n == 0) {
1457 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, iv, iv);
1458 if (ret != 0) {
Simon Butcherad4e4932018-04-29 00:43:47 +01001459 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001460 }
Simon Butcherad4e4932018-04-29 00:43:47 +01001461 }
Simon Butcher76a5b222018-04-22 22:57:27 +01001462 *output++ = *input++ ^ iv[n];
1463
Gilles Peskine449bd832023-01-11 14:50:10 +01001464 n = (n + 1) & 0x0F;
Simon Butcher76a5b222018-04-22 22:57:27 +01001465 }
1466
1467 *iv_off = n;
1468
Simon Butcherad4e4932018-04-29 00:43:47 +01001469exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001470 return ret;
Simon Butcher76a5b222018-04-22 22:57:27 +01001471}
1472#endif /* MBEDTLS_CIPHER_MODE_OFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001473
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001474#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001475/*
1476 * AES-CTR buffer encryption/decryption
1477 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001478int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
1479 size_t length,
1480 size_t *nc_off,
1481 unsigned char nonce_counter[16],
1482 unsigned char stream_block[16],
1483 const unsigned char *input,
1484 unsigned char *output)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001485{
Paul Bakker369e14b2012-04-18 14:16:09 +00001486 int c, i;
Gilles Peskine7820a572021-07-07 21:08:28 +02001487 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001488 size_t n;
1489
Manuel Pégourié-Gonnard2bc535b2018-12-13 11:08:36 +01001490 n = *nc_off;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001491
Gilles Peskine449bd832023-01-11 14:50:10 +01001492 if (n > 0x0F) {
1493 return MBEDTLS_ERR_AES_BAD_INPUT_DATA;
1494 }
Mohammad Azim Khan3f7f8172017-11-23 17:49:05 +00001495
Gilles Peskine449bd832023-01-11 14:50:10 +01001496 while (length--) {
1497 if (n == 0) {
1498 ret = mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block);
1499 if (ret != 0) {
Gilles Peskine7820a572021-07-07 21:08:28 +02001500 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001501 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001502
Gilles Peskine449bd832023-01-11 14:50:10 +01001503 for (i = 16; i > 0; i--) {
1504 if (++nonce_counter[i - 1] != 0) {
Paul Bakker369e14b2012-04-18 14:16:09 +00001505 break;
Gilles Peskine449bd832023-01-11 14:50:10 +01001506 }
1507 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001508 }
1509 c = *input++;
Gilles Peskine449bd832023-01-11 14:50:10 +01001510 *output++ = (unsigned char) (c ^ stream_block[n]);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001511
Gilles Peskine449bd832023-01-11 14:50:10 +01001512 n = (n + 1) & 0x0F;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001513 }
1514
1515 *nc_off = n;
Gilles Peskine7820a572021-07-07 21:08:28 +02001516 ret = 0;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001517
Gilles Peskine7820a572021-07-07 21:08:28 +02001518exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001519 return ret;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001520}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001521#endif /* MBEDTLS_CIPHER_MODE_CTR */
Manuel Pégourié-Gonnard1ec220b2014-03-10 11:20:17 +01001522
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523#endif /* !MBEDTLS_AES_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001525#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001526/*
1527 * AES test vectors from:
1528 *
1529 * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
1530 */
Yanray Wang62c99912023-05-11 11:06:53 +08001531static const unsigned char aes_test_ecb_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001532{
1533 { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
1534 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
Yanray Wang62c99912023-05-11 11:06:53 +08001535#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001536 { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
1537 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
1538 { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
1539 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
Yanray Wang62c99912023-05-11 11:06:53 +08001540#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001541};
1542
Yanray Wang62c99912023-05-11 11:06:53 +08001543static const unsigned char aes_test_ecb_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001544{
1545 { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
1546 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
Yanray Wang62c99912023-05-11 11:06:53 +08001547#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001548 { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
1549 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
1550 { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
1551 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001552#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001553};
1554
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001555#if defined(MBEDTLS_CIPHER_MODE_CBC)
Yanray Wang62c99912023-05-11 11:06:53 +08001556static const unsigned char aes_test_cbc_dec[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001557{
1558 { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
1559 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
Yanray Wang62c99912023-05-11 11:06:53 +08001560#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001561 { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
1562 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
1563 { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
1564 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
Yanray Wang62c99912023-05-11 11:06:53 +08001565#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001566};
1567
Yanray Wang62c99912023-05-11 11:06:53 +08001568static const unsigned char aes_test_cbc_enc[][16] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001569{
1570 { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
1571 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
Yanray Wang62c99912023-05-11 11:06:53 +08001572#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001573 { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
1574 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
1575 { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
1576 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
Yanray Wang62c99912023-05-11 11:06:53 +08001577#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001578};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001579#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00001580
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001581#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001582/*
1583 * AES-CFB128 test vectors from:
1584 *
1585 * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
1586 */
Yanray Wang62c99912023-05-11 11:06:53 +08001587static const unsigned char aes_test_cfb128_key[][32] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001588{
1589 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1590 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001591#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001592 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1593 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1594 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1595 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1596 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1597 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1598 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001599#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001600};
1601
1602static const unsigned char aes_test_cfb128_iv[16] =
1603{
1604 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1605 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1606};
1607
1608static const unsigned char aes_test_cfb128_pt[64] =
1609{
1610 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1611 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1612 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1613 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1614 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1615 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1616 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1617 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1618};
1619
Yanray Wang62c99912023-05-11 11:06:53 +08001620static const unsigned char aes_test_cfb128_ct[][64] =
Paul Bakker5121ce52009-01-03 21:22:43 +00001621{
1622 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1623 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1624 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
1625 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
1626 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
1627 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
1628 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
1629 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
Yanray Wang62c99912023-05-11 11:06:53 +08001630#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Paul Bakker5121ce52009-01-03 21:22:43 +00001631 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1632 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1633 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
1634 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
1635 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
1636 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
1637 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
1638 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
1639 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1640 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1641 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
1642 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
1643 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
1644 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
1645 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
1646 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
Yanray Wang62c99912023-05-11 11:06:53 +08001647#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00001648};
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001649#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001650
Simon Butcherad4e4932018-04-29 00:43:47 +01001651#if defined(MBEDTLS_CIPHER_MODE_OFB)
1652/*
1653 * AES-OFB test vectors from:
1654 *
Simon Butcher5db13622018-06-04 22:11:25 +01001655 * https://csrc.nist.gov/publications/detail/sp/800-38a/final
Simon Butcherad4e4932018-04-29 00:43:47 +01001656 */
Yanray Wang62c99912023-05-11 11:06:53 +08001657static const unsigned char aes_test_ofb_key[][32] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001658{
1659 { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
1660 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
Yanray Wang62c99912023-05-11 11:06:53 +08001661#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001662 { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
1663 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
1664 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
1665 { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
1666 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
1667 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
1668 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
Yanray Wang62c99912023-05-11 11:06:53 +08001669#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001670};
1671
1672static const unsigned char aes_test_ofb_iv[16] =
1673{
1674 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1675 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
1676};
1677
1678static const unsigned char aes_test_ofb_pt[64] =
1679{
1680 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
1681 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
1682 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
1683 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
1684 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
1685 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
1686 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
1687 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
1688};
1689
Yanray Wang62c99912023-05-11 11:06:53 +08001690static const unsigned char aes_test_ofb_ct[][64] =
Simon Butcherad4e4932018-04-29 00:43:47 +01001691{
1692 { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
1693 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
1694 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
1695 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
1696 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
1697 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
1698 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
1699 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e },
Yanray Wang62c99912023-05-11 11:06:53 +08001700#if !defined(MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH)
Simon Butcherad4e4932018-04-29 00:43:47 +01001701 { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
1702 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
1703 0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c,
1704 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
1705 0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f,
1706 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
1707 0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e,
1708 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a },
1709 { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
1710 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
1711 0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a,
1712 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
1713 0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed,
1714 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
1715 0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8,
1716 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84 }
Yanray Wang62c99912023-05-11 11:06:53 +08001717#endif
Simon Butcherad4e4932018-04-29 00:43:47 +01001718};
1719#endif /* MBEDTLS_CIPHER_MODE_OFB */
1720
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001721#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001722/*
1723 * AES-CTR test vectors from:
1724 *
1725 * http://www.faqs.org/rfcs/rfc3686.html
1726 */
1727
Yanray Wang62c99912023-05-11 11:06:53 +08001728static const unsigned char aes_test_ctr_key[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001729{
1730 { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
1731 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
1732 { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
1733 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
1734 { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
1735 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
1736};
1737
Yanray Wang62c99912023-05-11 11:06:53 +08001738static const unsigned char aes_test_ctr_nonce_counter[][16] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001739{
1740 { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
1741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
1742 { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
1743 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
1744 { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
1745 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
1746};
1747
Yanray Wang62c99912023-05-11 11:06:53 +08001748static const unsigned char aes_test_ctr_pt[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001749{
1750 { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
1751 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001752 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1753 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1754 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1755 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
1756
1757 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1758 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
1759 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
1760 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
1761 0x20, 0x21, 0x22, 0x23 }
1762};
1763
Yanray Wang62c99912023-05-11 11:06:53 +08001764static const unsigned char aes_test_ctr_ct[][48] =
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001765{
1766 { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
1767 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
1768 { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
1769 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
1770 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
1771 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
1772 { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
1773 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
1774 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
1775 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
1776 0x25, 0xB2, 0x07, 0x2F }
1777};
1778
1779static const int aes_test_ctr_len[3] =
Gilles Peskine449bd832023-01-11 14:50:10 +01001780{ 16, 32, 36 };
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001781#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00001782
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001783#if defined(MBEDTLS_CIPHER_MODE_XTS)
1784/*
1785 * AES-XTS test vectors from:
1786 *
1787 * IEEE P1619/D16 Annex B
1788 * https://web.archive.org/web/20150629024421/http://grouper.ieee.org/groups/1619/email/pdf00086.pdf
1789 * (Archived from original at http://grouper.ieee.org/groups/1619/email/pdf00086.pdf)
1790 */
1791static const unsigned char aes_test_xts_key[][32] =
1792{
1793 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1797 { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1798 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
1799 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1800 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1801 { 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
1802 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
1803 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
1804 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 },
1805};
1806
1807static const unsigned char aes_test_xts_pt32[][32] =
1808{
1809 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1813 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1814 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1815 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1816 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1817 { 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1818 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1819 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
1820 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44 },
1821};
1822
1823static const unsigned char aes_test_xts_ct32[][32] =
1824{
1825 { 0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
1826 0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
1827 0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
1828 0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e },
1829 { 0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
1830 0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
1831 0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
1832 0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0 },
1833 { 0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
1834 0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
1835 0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
1836 0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89 },
1837};
1838
1839static const unsigned char aes_test_xts_data_unit[][16] =
1840{
Gilles Peskine449bd832023-01-11 14:50:10 +01001841 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1843 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
1845 { 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
1846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
Jaeden Amero21d79cf2018-05-23 10:30:18 +01001847};
1848
1849#endif /* MBEDTLS_CIPHER_MODE_XTS */
1850
Paul Bakker5121ce52009-01-03 21:22:43 +00001851/*
1852 * Checkup routine
1853 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001854int mbedtls_aes_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +00001855{
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001856 int ret = 0, i, j, u, mode;
1857 unsigned int keybits;
Paul Bakker5121ce52009-01-03 21:22:43 +00001858 unsigned char key[32];
1859 unsigned char buf[64];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001860 const unsigned char *aes_tests;
Andrzej Kurek252283f2022-09-27 07:54:16 -04001861#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1862 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00001863 unsigned char iv[16];
Jussi Kivilinna4b541be2016-06-22 18:48:16 +03001864#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001865#if defined(MBEDTLS_CIPHER_MODE_CBC)
Manuel Pégourié-Gonnard92cb1d32013-09-13 16:24:20 +02001866 unsigned char prv[16];
1867#endif
Simon Butcher2ff0e522018-06-14 09:57:07 +01001868#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) || \
1869 defined(MBEDTLS_CIPHER_MODE_OFB)
Paul Bakker27fdf462011-06-09 13:55:13 +00001870 size_t offset;
Paul Bakkere91d01e2011-04-19 15:55:50 +00001871#endif
Simon Butcher66a89032018-06-15 18:20:29 +01001872#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_XTS)
Paul Bakkere91d01e2011-04-19 15:55:50 +00001873 int len;
Simon Butcher66a89032018-06-15 18:20:29 +01001874#endif
1875#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00001876 unsigned char nonce_counter[16];
1877 unsigned char stream_block[16];
1878#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001879 mbedtls_aes_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +00001880
Gilles Peskine449bd832023-01-11 14:50:10 +01001881 memset(key, 0, 32);
1882 mbedtls_aes_init(&ctx);
Paul Bakker5121ce52009-01-03 21:22:43 +00001883
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001884 if (verbose != 0) {
1885#if defined(MBEDTLS_AES_ALT)
1886 mbedtls_printf(" AES note: alternative implementation.\n");
1887#else /* MBEDTLS_AES_ALT */
1888#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
1889 if (mbedtls_padlock_has_support(MBEDTLS_PADLOCK_ACE)) {
1890 mbedtls_printf(" AES note: using VIA Padlock.\n");
1891 } else
1892#endif
1893#if defined(MBEDTLS_AESNI_HAVE_CODE)
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001894#if MBEDTLS_AESNI_HAVE_CODE == 1
Dave Rodgman086e1372023-06-16 20:21:39 +01001895 mbedtls_printf(" AES note: AESNI code present (assembly implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001896#elif MBEDTLS_AESNI_HAVE_CODE == 2
Dave Rodgman086e1372023-06-16 20:21:39 +01001897 mbedtls_printf(" AES note: AESNI code present (intrinsics implementation).\n");
Dave Rodgman96a9e6a2023-06-16 20:18:36 +01001898#else
1899#error Unrecognised value for MBEDTLS_AESNI_HAVE_CODE
1900#endif
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001901 if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
1902 mbedtls_printf(" AES note: using AESNI.\n");
1903 } else
1904#endif
1905#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64)
1906 if (mbedtls_aesce_has_support()) {
1907 mbedtls_printf(" AES note: using AESCE.\n");
1908 } else
1909#endif
Jerry Yu29c91ba2023-08-04 11:02:04 +08001910 {
1911#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
1912 mbedtls_printf(" AES note: built-in implementation.\n");
1913#endif
1914 }
Gilles Peskine7e67bd52023-03-10 22:35:24 +01001915#endif /* MBEDTLS_AES_ALT */
1916 }
1917
Paul Bakker5121ce52009-01-03 21:22:43 +00001918 /*
1919 * ECB mode
1920 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001921 {
1922 static const int num_tests =
1923 sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001924
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001925 for (i = 0; i < num_tests << 1; i++) {
1926 u = i >> 1;
1927 keybits = 128 + u * 64;
1928 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001929
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001930 if (verbose != 0) {
1931 mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
1932 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
1933 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08001934
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001935 memset(buf, 0, 16);
Gilles Peskine449bd832023-01-11 14:50:10 +01001936
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001937 if (mode == MBEDTLS_AES_DECRYPT) {
1938 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
1939 aes_tests = aes_test_ecb_dec[u];
1940 } else {
1941 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
1942 aes_tests = aes_test_ecb_enc[u];
1943 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001944
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001945 /*
1946 * AES-192 is an optional feature that may be unavailable when
1947 * there is an alternative underlying implementation i.e. when
1948 * MBEDTLS_AES_ALT is defined.
1949 */
1950 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
1951 mbedtls_printf("skipped\n");
1952 continue;
1953 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02001954 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01001955 }
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001956
1957 for (j = 0; j < 10000; j++) {
1958 ret = mbedtls_aes_crypt_ecb(&ctx, mode, buf, buf);
1959 if (ret != 0) {
1960 goto exit;
1961 }
1962 }
1963
1964 if (memcmp(buf, aes_tests, 16) != 0) {
1965 ret = 1;
1966 goto exit;
1967 }
1968
1969 if (verbose != 0) {
1970 mbedtls_printf("passed\n");
1971 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01001972 }
1973
Gilles Peskine449bd832023-01-11 14:50:10 +01001974 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001975 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01001976 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001977 }
1978
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001979#if defined(MBEDTLS_CIPHER_MODE_CBC)
Paul Bakker5121ce52009-01-03 21:22:43 +00001980 /*
1981 * CBC mode
1982 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001983 {
1984 static const int num_tests =
1985 sizeof(aes_test_cbc_dec) / sizeof(*aes_test_cbc_dec);
Paul Bakker5121ce52009-01-03 21:22:43 +00001986
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001987 for (i = 0; i < num_tests << 1; i++) {
1988 u = i >> 1;
1989 keybits = 128 + u * 64;
1990 mode = i & 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001991
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001992 if (verbose != 0) {
1993 mbedtls_printf(" AES-CBC-%3u (%s): ", keybits,
1994 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
Paul Bakker5121ce52009-01-03 21:22:43 +00001995 }
1996
Yanray Wang59c2dfa2023-05-11 12:04:23 +08001997 memset(iv, 0, 16);
1998 memset(prv, 0, 16);
1999 memset(buf, 0, 16);
2000
2001 if (mode == MBEDTLS_AES_DECRYPT) {
2002 ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
2003 aes_tests = aes_test_cbc_dec[u];
2004 } else {
2005 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2006 aes_tests = aes_test_cbc_enc[u];
2007 }
2008
2009 /*
2010 * AES-192 is an optional feature that may be unavailable when
2011 * there is an alternative underlying implementation i.e. when
2012 * MBEDTLS_AES_ALT is defined.
2013 */
2014 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2015 mbedtls_printf("skipped\n");
2016 continue;
2017 } else if (ret != 0) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002018 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002019 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002020
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002021 for (j = 0; j < 10000; j++) {
2022 if (mode == MBEDTLS_AES_ENCRYPT) {
2023 unsigned char tmp[16];
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002024
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002025 memcpy(tmp, prv, 16);
2026 memcpy(prv, buf, 16);
2027 memcpy(buf, tmp, 16);
2028 }
2029
2030 ret = mbedtls_aes_crypt_cbc(&ctx, mode, 16, iv, buf, buf);
2031 if (ret != 0) {
2032 goto exit;
2033 }
2034
2035 }
2036
2037 if (memcmp(buf, aes_tests, 16) != 0) {
2038 ret = 1;
2039 goto exit;
2040 }
2041
2042 if (verbose != 0) {
2043 mbedtls_printf("passed\n");
2044 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002045 }
2046
Gilles Peskine449bd832023-01-11 14:50:10 +01002047 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002048 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002049 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002050 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002051#endif /* MBEDTLS_CIPHER_MODE_CBC */
Paul Bakker5121ce52009-01-03 21:22:43 +00002052
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002053#if defined(MBEDTLS_CIPHER_MODE_CFB)
Paul Bakker5121ce52009-01-03 21:22:43 +00002054 /*
2055 * CFB128 mode
2056 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002057 {
2058 static const int num_tests =
2059 sizeof(aes_test_cfb128_key) / sizeof(*aes_test_cfb128_key);
Paul Bakker5121ce52009-01-03 21:22:43 +00002060
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002061 for (i = 0; i < num_tests << 1; i++) {
2062 u = i >> 1;
2063 keybits = 128 + u * 64;
2064 mode = i & 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002065
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002066 if (verbose != 0) {
2067 mbedtls_printf(" AES-CFB128-%3u (%s): ", keybits,
2068 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2069 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002070
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002071 memcpy(iv, aes_test_cfb128_iv, 16);
2072 memcpy(key, aes_test_cfb128_key[u], keybits / 8);
Paul Bakker5121ce52009-01-03 21:22:43 +00002073
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002074 offset = 0;
2075 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2076 /*
2077 * AES-192 is an optional feature that may be unavailable when
2078 * there is an alternative underlying implementation i.e. when
2079 * MBEDTLS_AES_ALT is defined.
2080 */
2081 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2082 mbedtls_printf("skipped\n");
2083 continue;
2084 } else if (ret != 0) {
2085 goto exit;
2086 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002087
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002088 if (mode == MBEDTLS_AES_DECRYPT) {
2089 memcpy(buf, aes_test_cfb128_ct[u], 64);
2090 aes_tests = aes_test_cfb128_pt;
2091 } else {
2092 memcpy(buf, aes_test_cfb128_pt, 64);
2093 aes_tests = aes_test_cfb128_ct[u];
2094 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002095
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002096 ret = mbedtls_aes_crypt_cfb128(&ctx, mode, 64, &offset, iv, buf, buf);
2097 if (ret != 0) {
2098 goto exit;
2099 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002100
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002101 if (memcmp(buf, aes_tests, 64) != 0) {
2102 ret = 1;
2103 goto exit;
2104 }
2105
2106 if (verbose != 0) {
2107 mbedtls_printf("passed\n");
2108 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002109 }
2110
Gilles Peskine449bd832023-01-11 14:50:10 +01002111 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002112 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002113 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002114 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002115#endif /* MBEDTLS_CIPHER_MODE_CFB */
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002116
Simon Butcherad4e4932018-04-29 00:43:47 +01002117#if defined(MBEDTLS_CIPHER_MODE_OFB)
2118 /*
2119 * OFB mode
2120 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002121 {
2122 static const int num_tests =
2123 sizeof(aes_test_ofb_key) / sizeof(*aes_test_ofb_key);
Simon Butcherad4e4932018-04-29 00:43:47 +01002124
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002125 for (i = 0; i < num_tests << 1; i++) {
2126 u = i >> 1;
2127 keybits = 128 + u * 64;
2128 mode = i & 1;
Simon Butcherad4e4932018-04-29 00:43:47 +01002129
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002130 if (verbose != 0) {
2131 mbedtls_printf(" AES-OFB-%3u (%s): ", keybits,
2132 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2133 }
Arto Kinnunen0f066182023-04-20 10:02:46 +08002134
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002135 memcpy(iv, aes_test_ofb_iv, 16);
2136 memcpy(key, aes_test_ofb_key[u], keybits / 8);
Simon Butcherad4e4932018-04-29 00:43:47 +01002137
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002138 offset = 0;
2139 ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
2140 /*
2141 * AES-192 is an optional feature that may be unavailable when
2142 * there is an alternative underlying implementation i.e. when
2143 * MBEDTLS_AES_ALT is defined.
2144 */
2145 if (ret == MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED && keybits == 192) {
2146 mbedtls_printf("skipped\n");
2147 continue;
2148 } else if (ret != 0) {
2149 goto exit;
2150 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002151
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002152 if (mode == MBEDTLS_AES_DECRYPT) {
2153 memcpy(buf, aes_test_ofb_ct[u], 64);
2154 aes_tests = aes_test_ofb_pt;
2155 } else {
2156 memcpy(buf, aes_test_ofb_pt, 64);
2157 aes_tests = aes_test_ofb_ct[u];
2158 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002159
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002160 ret = mbedtls_aes_crypt_ofb(&ctx, 64, &offset, iv, buf, buf);
2161 if (ret != 0) {
2162 goto exit;
2163 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002164
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002165 if (memcmp(buf, aes_tests, 64) != 0) {
2166 ret = 1;
2167 goto exit;
2168 }
2169
2170 if (verbose != 0) {
2171 mbedtls_printf("passed\n");
2172 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002173 }
2174
Gilles Peskine449bd832023-01-11 14:50:10 +01002175 if (verbose != 0) {
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002176 mbedtls_printf("\n");
Gilles Peskine449bd832023-01-11 14:50:10 +01002177 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002178 }
Simon Butcherad4e4932018-04-29 00:43:47 +01002179#endif /* MBEDTLS_CIPHER_MODE_OFB */
2180
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002181#if defined(MBEDTLS_CIPHER_MODE_CTR)
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002182 /*
2183 * CTR mode
2184 */
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002185 {
2186 static const int num_tests =
2187 sizeof(aes_test_ctr_key) / sizeof(*aes_test_ctr_key);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002188
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002189 for (i = 0; i < num_tests << 1; i++) {
2190 u = i >> 1;
2191 mode = i & 1;
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002192
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002193 if (verbose != 0) {
2194 mbedtls_printf(" AES-CTR-128 (%s): ",
2195 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2196 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002197
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002198 memcpy(nonce_counter, aes_test_ctr_nonce_counter[u], 16);
2199 memcpy(key, aes_test_ctr_key[u], 16);
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002200
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002201 offset = 0;
2202 if ((ret = mbedtls_aes_setkey_enc(&ctx, key, 128)) != 0) {
2203 goto exit;
2204 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002205
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002206 len = aes_test_ctr_len[u];
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002207
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002208 if (mode == MBEDTLS_AES_DECRYPT) {
2209 memcpy(buf, aes_test_ctr_ct[u], len);
2210 aes_tests = aes_test_ctr_pt[u];
2211 } else {
2212 memcpy(buf, aes_test_ctr_pt[u], len);
2213 aes_tests = aes_test_ctr_ct[u];
2214 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002215
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002216 ret = mbedtls_aes_crypt_ctr(&ctx, len, &offset, nonce_counter,
2217 stream_block, buf, buf);
2218 if (ret != 0) {
2219 goto exit;
2220 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002221
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002222 if (memcmp(buf, aes_tests, len) != 0) {
2223 ret = 1;
2224 goto exit;
2225 }
2226
2227 if (verbose != 0) {
2228 mbedtls_printf("passed\n");
2229 }
Gilles Peskine449bd832023-01-11 14:50:10 +01002230 }
Paul Bakkerb6ecaf52011-04-19 14:29:23 +00002231 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002232
Gilles Peskine449bd832023-01-11 14:50:10 +01002233 if (verbose != 0) {
2234 mbedtls_printf("\n");
2235 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002236#endif /* MBEDTLS_CIPHER_MODE_CTR */
Paul Bakker5121ce52009-01-03 21:22:43 +00002237
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002238#if defined(MBEDTLS_CIPHER_MODE_XTS)
Yanray Wang59c2dfa2023-05-11 12:04:23 +08002239 /*
2240 * XTS mode
2241 */
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002242 {
Gilles Peskine449bd832023-01-11 14:50:10 +01002243 static const int num_tests =
2244 sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
2245 mbedtls_aes_xts_context ctx_xts;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002246
Gilles Peskine449bd832023-01-11 14:50:10 +01002247 mbedtls_aes_xts_init(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002248
Gilles Peskine449bd832023-01-11 14:50:10 +01002249 for (i = 0; i < num_tests << 1; i++) {
2250 const unsigned char *data_unit;
2251 u = i >> 1;
2252 mode = i & 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002253
Gilles Peskine449bd832023-01-11 14:50:10 +01002254 if (verbose != 0) {
2255 mbedtls_printf(" AES-XTS-128 (%s): ",
2256 (mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
2257 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002258
Gilles Peskine449bd832023-01-11 14:50:10 +01002259 memset(key, 0, sizeof(key));
2260 memcpy(key, aes_test_xts_key[u], 32);
2261 data_unit = aes_test_xts_data_unit[u];
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002262
Gilles Peskine449bd832023-01-11 14:50:10 +01002263 len = sizeof(*aes_test_xts_ct32);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002264
Gilles Peskine449bd832023-01-11 14:50:10 +01002265 if (mode == MBEDTLS_AES_DECRYPT) {
2266 ret = mbedtls_aes_xts_setkey_dec(&ctx_xts, key, 256);
2267 if (ret != 0) {
2268 goto exit;
2269 }
2270 memcpy(buf, aes_test_xts_ct32[u], len);
2271 aes_tests = aes_test_xts_pt32[u];
2272 } else {
2273 ret = mbedtls_aes_xts_setkey_enc(&ctx_xts, key, 256);
2274 if (ret != 0) {
2275 goto exit;
2276 }
2277 memcpy(buf, aes_test_xts_pt32[u], len);
2278 aes_tests = aes_test_xts_ct32[u];
2279 }
2280
2281
2282 ret = mbedtls_aes_crypt_xts(&ctx_xts, mode, len, data_unit,
2283 buf, buf);
2284 if (ret != 0) {
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002285 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002286 }
2287
2288 if (memcmp(buf, aes_tests, len) != 0) {
2289 ret = 1;
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002290 goto exit;
Gilles Peskine449bd832023-01-11 14:50:10 +01002291 }
2292
2293 if (verbose != 0) {
2294 mbedtls_printf("passed\n");
2295 }
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002296 }
2297
Gilles Peskine449bd832023-01-11 14:50:10 +01002298 if (verbose != 0) {
2299 mbedtls_printf("\n");
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002300 }
2301
Gilles Peskine449bd832023-01-11 14:50:10 +01002302 mbedtls_aes_xts_free(&ctx_xts);
Jaeden Amero21d79cf2018-05-23 10:30:18 +01002303 }
2304#endif /* MBEDTLS_CIPHER_MODE_XTS */
2305
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002306 ret = 0;
2307
2308exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01002309 if (ret != 0 && verbose != 0) {
2310 mbedtls_printf("failed\n");
2311 }
Andres Amaya Garcia58f98c22017-06-14 16:19:42 +01002312
Gilles Peskine449bd832023-01-11 14:50:10 +01002313 mbedtls_aes_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +02002314
Gilles Peskine449bd832023-01-11 14:50:10 +01002315 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +00002316}
2317
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002318#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002319
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002320#endif /* MBEDTLS_AES_C */